Releases: objectstack-ai/framework
@objectstack/metadata@4.1.1
Patch Changes
- @objectstack/spec@4.1.1
- @objectstack/core@4.1.1
- @objectstack/types@4.1.1
- @objectstack/platform-objects@4.1.1
@objectstack/metadata-fs@5.1.0
Patch Changes
-
75f4ee6: feat(metadata): introduce
executionPinnedcapability for runtime version pinning (ADR-0009)Adds a new capability flag on the metadata type registry so that types whose runtime
transaction rows reference a specific historical version (flow, workflow, approval)
get unified pinning behavior — instead of every business table re-implementing its
own snapshot column.MetadataTypeRegistryEntrySchemagainsexecutionPinned: boolean, enforced
invariantexecutionPinned ⇒ supportsVersioning.flow,workflow,approvalflipped toexecutionPinned: true.approval
also corrected tosupportsVersioning: true(it was wronglyfalse).MetadataRepository.getByHash(ref, hash)added to the interface. Production
implementation inSysMetadataRepositoryresolves historical bodies through
sys_metadata_historykeyed by(organization_id, type, name, checksum).
In-memory and FS repositories serve HEAD-only matches.sys_metadata_historygains an index on(organization_id, type, name, checksum)
to keep hash lookups O(log n).HistoryCleanupManagerskips pinned types entirely (both age-based and
count-based retention) — pinned-type history must never be GC'd.
See
docs/adr/0009-execution-pinned-metadata.mdfor full rationale and the
list of rejected alternatives (no shared snapshot table, no inlined snapshot column). -
Updated dependencies [75f4ee6]
- @objectstack/metadata-core@5.1.0
@objectstack/metadata-fs@5.0.0
Minor Changes
-
5e9dcb4: BREAKING — metadata: remove
projectandbranchfromMetaRefThe metadata layer no longer models project or branch. Customisation is now
scoped purely to organisation. Project remains exclusively as an artifact
packaging concept (theobjectstack.jsonbundle envelope); branching is left
to Git.What changed:
MetaRefis now{ org, type, name, version? }(was
{ org, project, branch, type, name, version? }).refKey()is the two
segment string${org}/${type}/${name}(was five segments).MetadataItem.seqis monotonic per org (was per branch).BranchRef,MergeStrategy,MergeResulttypes and the optional
fork/mergemethods onMetadataRepositoryare removed.ListFilter/WatchFilter/HistoryOptionsno longer acceptproject
orbranch.FileSystemRepositorydisk layout simplified to
<root>/<type>/<name>.json(was<root>/<project>/<branch>/<type>/<name>.json);
change-log path is now.objectstack/.log/main.jsonlregardless of any
branch concept. Constructor no longer acceptsproject/branch.SysMetadataRepository: removedprojectLabel/branchLabeloptions;
thesys_metadataschema'sproject_id/branchcolumns (if present)
are ignored. A future major release willDROPthem.MetadataManager.setRepository(repo, opts)no longer takes an opts object
withbranch.
Migration:
-const ref = { org: 'acme', project: 'crm', branch: 'main', type: 'view', name: 'home' }; +const ref = { org: 'acme', type: 'view', name: 'home' }; -new FileSystemRepository({ root, org: 'acme', project: 'crm', branch: 'main' }); +new FileSystemRepository({ root, org: 'acme' });
Existing
sys_metadatarows continue to load; the deprecated columns are
ignored at read time. -
32ce912: Add
@objectstack/metadata-fs— Node-onlyFileSystemRepository
implementation of the M0 Repository contract.Layout:
<root>/ <type>/<name>.json # canonical body (atomic rename writes) .objectstack/.log/<branch>.jsonl # append-only change logFeatures:
- All 17 contract tests pass (
singleBranch: true). - Per-key serialization via
KeyedMutex. - Atomic writes via tmpfile + rename.
- Heads and
seqrecovered from the JSONL log onstart()— survives
process restart. - chokidar watcher translates external edits (e.g. VSCode saves) into
MetadataEvents withsource: 'fs'. - Self-write suppression: 200ms window prevents the watcher from
re-emitting events for files we wrote ourselves. - Manual
AsyncIteratorforwatch()to mirror the in-memory pattern.
Also (
metadata-core):- Add
singleBranchoption torunRepositoryContractTestsso
single-branch backends (like the FS one) skip the cross-branch test. - Switch tsup
splitting: truesoindex.jsandtesting.jsshare a
singleConflictErrorclass identity (was double-bundled before).
See ADR-0008 §10 PR-4.
- All 17 contract tests pass (
Patch Changes
-
96ad4df: Fix dev-mode HMR data-reload for
*.view.ts/*.flow.tssource-file edits.Three coordinated fixes close the long-standing gap where editing a
declarative-metadata source file in dev (e.g.case.view.ts) would
recompiledist/objectstack.jsonbut the running server kept serving
the stale boot-time value:-
@objectstack/objectql—ObjectStackProtocolImplementation.getMetaItem
now consultsMetadataService(HMR-aware) before the in-memory
SchemaRegistry(boot-time cache). Previously the registry shadowed
freshly-registered values:manager.register('view','case',newDef)
updated MetadataManager butgetMetaItemreturned the stale registry
copy because step 2 (registry) ran before step 3 (service). Reordered
to "1. sys_metadata overlay → 2. MetadataService → 3. SchemaRegistry". -
@objectstack/runtime—createStandaloneStacknow enables the
MetadataPluginartifact-file watcher in non-production environments
(NODE_ENV !== 'production'). Previously hard-coded towatch: false,
leaving nothing watchingdist/objectstack.jsonwhen the CLI dev mode
recompiled it. -
@objectstack/metadata&@objectstack/metadata-fs— Both
chokidar watchers now useusePolling: trueto avoidfs.watch
EMFILE on macOS / busy dev hosts where the native file-descriptor
pool can be exhausted by other long-running node processes.
With these three changes:
- CLI edits source → recompile artifact (~400ms)
- Server's polling chokidar detects artifact change →
_loadFromLocalFile _loadFromLocalFilecallsmanager.register(type, name, item)- MetadataService now has the fresh value
- Read path returns the fresh value via the new step-2 lookup
- Studio SSE listeners re-render
-
-
Updated dependencies [5e9dcb4]
-
Updated dependencies [4150fe4]
-
Updated dependencies [8337cdb]
-
Updated dependencies [58835a6]
-
Updated dependencies [8cc30b4]
-
Updated dependencies [32ce912]
- @objectstack/metadata-core@5.0.0
@objectstack/metadata-core@5.1.0
Minor Changes
-
75f4ee6: feat(metadata): introduce
executionPinnedcapability for runtime version pinning (ADR-0009)Adds a new capability flag on the metadata type registry so that types whose runtime
transaction rows reference a specific historical version (flow, workflow, approval)
get unified pinning behavior — instead of every business table re-implementing its
own snapshot column.MetadataTypeRegistryEntrySchemagainsexecutionPinned: boolean, enforced
invariantexecutionPinned ⇒ supportsVersioning.flow,workflow,approvalflipped toexecutionPinned: true.approval
also corrected tosupportsVersioning: true(it was wronglyfalse).MetadataRepository.getByHash(ref, hash)added to the interface. Production
implementation inSysMetadataRepositoryresolves historical bodies through
sys_metadata_historykeyed by(organization_id, type, name, checksum).
In-memory and FS repositories serve HEAD-only matches.sys_metadata_historygains an index on(organization_id, type, name, checksum)
to keep hash lookups O(log n).HistoryCleanupManagerskips pinned types entirely (both age-based and
count-based retention) — pinned-type history must never be GC'd.
See
docs/adr/0009-execution-pinned-metadata.mdfor full rationale and the
list of rejected alternatives (no shared snapshot table, no inlined snapshot column).
@objectstack/metadata-core@5.0.0
Minor Changes
-
5e9dcb4: BREAKING — metadata: remove
projectandbranchfromMetaRefThe metadata layer no longer models project or branch. Customisation is now
scoped purely to organisation. Project remains exclusively as an artifact
packaging concept (theobjectstack.jsonbundle envelope); branching is left
to Git.What changed:
MetaRefis now{ org, type, name, version? }(was
{ org, project, branch, type, name, version? }).refKey()is the two
segment string${org}/${type}/${name}(was five segments).MetadataItem.seqis monotonic per org (was per branch).BranchRef,MergeStrategy,MergeResulttypes and the optional
fork/mergemethods onMetadataRepositoryare removed.ListFilter/WatchFilter/HistoryOptionsno longer acceptproject
orbranch.FileSystemRepositorydisk layout simplified to
<root>/<type>/<name>.json(was<root>/<project>/<branch>/<type>/<name>.json);
change-log path is now.objectstack/.log/main.jsonlregardless of any
branch concept. Constructor no longer acceptsproject/branch.SysMetadataRepository: removedprojectLabel/branchLabeloptions;
thesys_metadataschema'sproject_id/branchcolumns (if present)
are ignored. A future major release willDROPthem.MetadataManager.setRepository(repo, opts)no longer takes an opts object
withbranch.
Migration:
-const ref = { org: 'acme', project: 'crm', branch: 'main', type: 'view', name: 'home' }; +const ref = { org: 'acme', type: 'view', name: 'home' }; -new FileSystemRepository({ root, org: 'acme', project: 'crm', branch: 'main' }); +new FileSystemRepository({ root, org: 'acme' });
Existing
sys_metadatarows continue to load; the deprecated columns are
ignored at read time. -
4150fe4: Add
MetadataCache— bounded, event-invalidated LRU sitting in front of
anyMetadataRepository. Features:- Bounded by
maxEntriesandmaxBytes(default 1024 / 8 MiB). - LRU eviction with touch-on-read.
- Lazy fill on read miss; negative caching for known-absent items.
- Subscribes to
repo.watch(filter)and invalidates affected entries
(including rename: both old and new keys). - Coalesces concurrent reads for the same key onto a single backend
fetch (thundering-herd safe). - Generation counter discards in-flight fetches that race an
invalidation, preventing stale-cache poisoning. - Diagnostics via
getStats()(entries, bytes, hits, misses,
invalidations, coalesced).
Includes a property-based test that verifies cache→repo convergence
under randomly-generated update sequences.See ADR-0008 §10 PR-3.
- Bounded by
-
8337cdb: Add
InMemoryRepository(reference implementation) and a parameterised
Repository contract test suite. The contract suite, exposed at
@objectstack/metadata-core/testing, verifies the seven invariants every
backend must satisfy (atomic put, monotonic seq per branch, optimistic
locking, canonical hashing, event ordering, watch resumability,
tombstones).Includes implementation-specific tests covering the injected clock,
canonical-hash insertion-order independence, and deep-copy isolation
between caller and store.See ADR-0008 §10 PR-2.
-
58835a6: Add
LayeredRepository— composes NMetadataRepositorys into a
read-through stack. Reads walk top-to-bottom; writes route to the
topmost writable layer;list()deduplicates byrefKeypreferring
the top;history()andwatch()merge events from all layers,
tagging each event'ssourcewith<layer>:<original-source>. The
multiplexedwatch()correctly cancels all child iterators when the
consumer callsreturn().Enables the canonical "system built-ins under user overlay" pattern
described in ADR-0008.See ADR-0008 §10 PR-5.
-
8cc30b4: New package: Repository contracts for the metadata lifecycle (ADR-0008).
Definitions only — no I/O. Exports Zod schemas, the
MetadataRepositoryinterface, canonical-form helpers
(canonicalize,hashSpec), and typed errors (ConflictError,
NotFoundError,SchemaValidationError).This is M0 PR-1 of the four-layer metadata refactor. Subsequent PRs
addInMemoryRepository,MetadataCache,FileSystemRepository
and migrate the existingMetadataManager/ HMR plumbing onto the
new contracts.
Patch Changes
-
32ce912: Add
@objectstack/metadata-fs— Node-onlyFileSystemRepository
implementation of the M0 Repository contract.Layout:
<root>/ <type>/<name>.json # canonical body (atomic rename writes) .objectstack/.log/<branch>.jsonl # append-only change logFeatures:
- All 17 contract tests pass (
singleBranch: true). - Per-key serialization via
KeyedMutex. - Atomic writes via tmpfile + rename.
- Heads and
seqrecovered from the JSONL log onstart()— survives
process restart. - chokidar watcher translates external edits (e.g. VSCode saves) into
MetadataEvents withsource: 'fs'. - Self-write suppression: 200ms window prevents the watcher from
re-emitting events for files we wrote ourselves. - Manual
AsyncIteratorforwatch()to mirror the in-memory pattern.
Also (
metadata-core):- Add
singleBranchoption torunRepositoryContractTestsso
single-branch backends (like the FS one) skip the cross-branch test. - Switch tsup
splitting: truesoindex.jsandtesting.jsshare a
singleConflictErrorclass identity (was double-bundled before).
See ADR-0008 §10 PR-4.
- All 17 contract tests pass (
@objectstack/hono@5.1.0
Patch Changes
- @objectstack/plugin-hono-server@5.1.0
@objectstack/hono@5.0.0
@objectstack/hono@4.2.0
Patch Changes
- @objectstack/plugin-hono-server@4.2.0
@objectstack/hono@4.1.1
Patch Changes
- @objectstack/plugin-hono-server@4.1.1