Immutable
release. Only release title and notes can be modified.
Added
docs/cross-package-typing.md— an end-to-end guide for a registry-in-one-package,
consumer-in-another setup: CURIE$refauthoring,InferTypewith a CURIE-keyed
reference map, and whyinstantiate()'s own return type — keyed by the registry's
absolute$ids — cannot be trusted across a package boundary, with the recommended
re-derive-locally idiom.
Changed
- Adopted
@studnicky/eslint-config. All 31 custom rules (@studnicky/*and
@studnicky/v8/*) run aserrorproject-wide. Resolving the resulting violations
drove several structural changes:- BREAKING: six package entry points restructured from flat files to
<name>/index.tsdirectories (src/value.ts→src/value/index.ts, and
likewise forschema,ontology,owl-gen,owl-gen-node,viz) to satisfy
no-export-alias. Deep imports must update fromsrc/<name>.jsto
src/<name>/index.js; the packageexportsmap subpaths (json-tology/value,
json-tology/schema, etc.) are unaffected. JsonSchemaObjectTypeis now composed viaOmit<JsonSchemaDocumentObjectType, Keys> & { retyped fields }instead of duplicating the nested-schema field list,
satisfyingno-prefer-existing-typewhile preserving full type accuracy.QuadInterfacere-declared asinterface QuadInterface extends Quad {}instead
of a type re-export, satisfyingno-export-alias.- ~200 freestanding functions across
src/modules/regrouped onto domain objects
(noun.verb()static methods), satisfyingno-freestanding-verb-noun.
- BREAKING: six package entry points restructured from flat files to
- BREAKING: constants-module exports use SCREAMING_SNAKE_CASE. 24 exported
constants insrc/constants/are renamed for consistency with the project's
constants-naming convention. Runtime string values are unchanged — only the
TypeScript identifier changes; update imports and references accordingly.src/constants/ERROR_CODES.ts:SchemaErrorCode→SCHEMA_ERROR_CODE,
GraphErrorCode→GRAPH_ERROR_CODE,InstantiationErrorCode→
INSTANTIATION_ERROR_CODE,MaterializationErrorCode→
MATERIALIZATION_ERROR_CODE,OwlImportErrorCode→OWL_IMPORT_ERROR_CODE,
TransformErrorCode→TRANSFORM_ERROR_CODE,CoercionErrorCode→
COERCION_ERROR_CODE,SchemaLoadErrorCode→SCHEMA_LOAD_ERROR_CODE.src/constants/BASE_SCHEMAS.ts:DurationDef→DURATION_DEF,
ErrorDetailsDef→ERROR_DETAILS_DEF,ProgressDef→PROGRESS_DEF,
TimedDef→TIMED_DEF,TimestampedDef→TIMESTAMPED_DEF,
ResponseDef→RESPONSE_DEF,ResultDef→RESULT_DEF,
StateSnapshotDef→STATE_SNAPSHOT_DEF,SortOrderDef→
SORT_ORDER_DEF,CursorDef→CURSOR_DEF,PaginationDef→
PAGINATION_DEF,FilterDef→FILTER_DEF,PageDef→PAGE_DEF.src/constants/SCHEMAS.ts:SchemaLoadErrorSchema→
SCHEMA_LOAD_ERROR_SCHEMA,SchemaLoadResultSchema→
SCHEMA_LOAD_RESULT_SCHEMA,ValidationErrorSchema→
VALIDATION_ERROR_SCHEMA.
- Schema-derived types are mutable by default. Every type-producing surface
(InferType,InferSchemaType,MaterializedSchemaType,ParseOutputType,
CanonicalShapeType/UnbrandType,BrandOutputType) types object properties and
array/tuple elements as plain mutable TypeScript (T[],{ id: string }) instead of
readonly T[]/ReadonlyArray<T>/{ readonly id: string }. A mutable array is
assignable wherever areadonlyarray is expected but not the reverse, so existing
call sites that already treat generated values as read-only are unaffected; consumers
who need immutability opt in locally with their ownreadonly/Readonly<T>
annotation. See Mutability. Transform.create'sdecodeaccepts a partial return.decodeis now typed
(raw: TWire) => Partial<CanonicalShapeType<TSchema, TReferences>>instead of the
full canonical shape, matching runtime behavior:instantiate(..., { enableDefaults: true })already runsdecodebefore filling schema defaults and validating, so a
normalizedecodethat only transforms a few wire fields no longer needs to
duplicate every schemadefaultor use a type assertion.encode's parameter type
is unchanged (it consumes the full, validated canonical value).
Fixed
- CI: GitHub Packages installs now declare
packages: read. Every job that
installs@studnicky/eslint-configfrom GitHub Packages grants thepackages: read
permission (orwritefor the publish jobs) alongsideNODE_AUTH_TOKEN; the token
alone is not sufficient for cross-repo package reads without the matching
permissions:declaration. - CI:
publish-gpr.ymlnow triggers on tag push (v*.*.*), not onlyrelease: published. A release created byrelease.ymlruns underGITHUB_TOKENand does not cascade thereleaseevent, so GPR publish never auto-fired; the tag-push trigger (a human/CLIgit push origin vX.Y.Z) fixes it. A concurrency guard prevents a double-publish when both triggers fire for a human/PAT release. - Release flow documented in
docs/releasing.md: merge-commit-based release/back-merge keepsmainanddevelopconvergent (the prior squash-only + linear-history policy made them diverge at every release). - Full-IRI
#fragment$refs matching a registered hash-namespace$id(e.g.
https://ns#Class, the idiomatic OWL/RDF form) now resolve correctly, at both
schema-registration time and validate/instantiate/materialize/dump runtime. Every
$refresolution site (SchemaRefWalker,RefResolution,SchemaCompilerPlan,
Dumper,RefDecoder) tries the literal$refstring against the registry before
falling back to document-fragment semantics, which previously stripped everything
from#onward and looked up a base IRI that was never registered. CURIE refs,
fragment-less path IRIs, and in-document#-only fragment refs are unaffected. docs/instantiate-vs-materialize.mdand four related pages stated the decode/default
ordering backwards (validate-then-decode instead of the actual decode-then-validate).
Fixed, with a canonical ordering statement and a passthrough-decode example.
Removed
docs/proposals/specialized-per-schema-validators.md— a deferred/not-planned
performance proposal with a named revisit trigger, not an open item.