@objectstack/objectql 9.2.0 → 9.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -98,6 +98,22 @@ interface SchemaRegistryOptions {
98
98
  * (useful in tests).
99
99
  */
100
100
  multiTenant?: boolean;
101
+ /**
102
+ * Policy for cross-package base-layer metadata collisions (ADR-0048) — two
103
+ * different code packages registering a bare-named generic item under the
104
+ * same `(type, name)`.
105
+ *
106
+ * - `'error'` (default): throw {@link MetadataCollisionError} at registration
107
+ * time, naming both packages and the type/name. Makes the otherwise-silent
108
+ * last-write-wins shadowing a loud, actionable failure.
109
+ * - `'warn'`: log a warning and let the registration proceed. For deliberate
110
+ * migrations where a collision is temporarily expected.
111
+ *
112
+ * Sourced from `OS_METADATA_COLLISION` (`warn` to downgrade) when not set
113
+ * explicitly. Legitimate runtime/DB overlays and same-package reloads are
114
+ * never treated as collisions regardless of this setting.
115
+ */
116
+ collisionPolicy?: 'error' | 'warn';
101
117
  }
102
118
  /**
103
119
  * Augment a registered object with implicit system fields.
@@ -132,6 +148,8 @@ declare class SchemaRegistry {
132
148
  private _logLevel;
133
149
  /** Whether to auto-inject multi-tenant system fields. */
134
150
  private readonly multiTenant;
151
+ /** Cross-package base-layer collision policy (ADR-0048). */
152
+ private readonly collisionPolicy;
135
153
  constructor(options?: SchemaRegistryOptions);
136
154
  get logLevel(): RegistryLogLevel;
137
155
  set logLevel(level: RegistryLogLevel);
@@ -258,6 +276,15 @@ declare class SchemaRegistry {
258
276
  * Universal Register Method for non-object metadata.
259
277
  */
260
278
  registerItem<T>(type: string, item: T, keyField?: keyof T, packageId?: string): void;
279
+ /**
280
+ * Find a code package OTHER than `incoming` that already owns `baseName` in
281
+ * `collection` (ADR-0048 cross-package collision detection). Scans the live
282
+ * collection — like {@link getItem} / {@link unregisterItem} — so it always
283
+ * reflects current state with no parallel index to drift across
284
+ * reset/unregister. Returns the conflicting owner's package id, or undefined
285
+ * when the name is free or only held by the same package / a runtime overlay.
286
+ */
287
+ private findOtherPackageOwner;
261
288
  /**
262
289
  * Validate Metadata against Spec Zod Schemas
263
290
  */
@@ -270,6 +297,38 @@ declare class SchemaRegistry {
270
297
  * Universal Get Method
271
298
  */
272
299
  getItem<T>(type: string, name: string): T | undefined;
300
+ /**
301
+ * Artifact-only lookup (ADR-0010 §3.3). Unlike {@link getItem} — which
302
+ * returns the plain-key entry first, so a runtime/DB-rehydrated row
303
+ * registered under the bare name SHADOWS the packaged artifact — this
304
+ * scans the composite (`<packageId>:<name>`) entries first and only
305
+ * returns an item whose `_packageId` marks a genuine code package
306
+ * (truthy and not the `'sys_metadata'` rehydration sentinel).
307
+ *
308
+ * This is what the protocol's lock/provenance resolution must use:
309
+ * the artifact's `_lock` envelope always wins over an overlay, and an
310
+ * overlay row hydrated into the plain key must never be able to mask
311
+ * it (that masking is exactly the "registry pollution" bug where a
312
+ * locked app's `_lock` read back as undefined after a PUT+GET).
313
+ */
314
+ getArtifactItem<T>(type: string, name: string): T | undefined;
315
+ /**
316
+ * Remove a plain-key runtime shadow so the packaged artifact registered
317
+ * under a composite key becomes the visible value again. Used by the
318
+ * metadata reset path (`deleteMetaItem`): deleting the `sys_metadata`
319
+ * overlay row must also heal the in-memory registry, otherwise the
320
+ * stale overlay copy keeps shadowing the artifact until restart.
321
+ *
322
+ * Deliberately conservative: the plain-key entry is only deleted when a
323
+ * packaged artifact still exists under a composite key, so the name
324
+ * stays resolvable afterwards. A runtime-only item (no artifact
325
+ * backing) is left untouched. Note the plain entry's own `_packageId`
326
+ * is NOT consulted — the hydration path grafts the artifact envelope
327
+ * onto the shadow (ADR-0010 §3.3), so a stamped `_packageId` does not
328
+ * mean the plain entry IS the artifact registration; artifact loaders
329
+ * always register under a composite key.
330
+ */
331
+ removeRuntimeShadow(type: string, name: string): boolean;
273
332
  /**
274
333
  * Universal List Method
275
334
  */
@@ -621,6 +680,8 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
621
680
  method?: "POST" | "PUT" | "DELETE" | "PATCH" | undefined;
622
681
  bodyExtra?: Record<string, unknown> | undefined;
623
682
  mode?: "custom" | "create" | "delete" | "edit" | undefined;
683
+ opensInNewTab?: boolean | undefined;
684
+ newTabUrl?: string | undefined;
624
685
  timeout?: number | undefined;
625
686
  aria?: {
626
687
  ariaLabel?: string | undefined;
@@ -1244,6 +1305,26 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
1244
1305
  * stale schema into the registry.
1245
1306
  */
1246
1307
  private applyObjectRegistryMutation;
1308
+ /**
1309
+ * Heal the in-memory registry after a metadata reset (overlay-row
1310
+ * delete) on control-plane kernels. Two layers:
1311
+ *
1312
+ * 1. Drop the plain-key runtime shadow so the packaged artifact
1313
+ * (registered under `<packageId>:<name>`) becomes the visible
1314
+ * value again. The shadow is written by the overlay-hydration
1315
+ * paths (`getMetaItems` / `loadMetaFromDb`) and — pre-fix —
1316
+ * survived the reset until restart, leaving stale overlay
1317
+ * content (and a stripped `_lock` envelope) in every
1318
+ * registry-direct read (ADR-0010 §3.3).
1319
+ * 2. When no composite-key artifact exists, fall back to the
1320
+ * MetadataService baseline (FilesystemLoader-sourced types) and
1321
+ * re-register it, preserving the historical refresh behaviour
1322
+ * for items the SchemaRegistry never held as artifacts.
1323
+ *
1324
+ * Best-effort: a failure must never block the delete that already
1325
+ * succeeded; the next full reload fixes the registry anyway.
1326
+ */
1327
+ private restoreArtifactRegistryView;
1247
1328
  /**
1248
1329
  * Ensure a just-PUBLISHED object's physical table exists so it is usable
1249
1330
  * for data CRUD immediately — without a server restart. Registering the
package/dist/index.d.ts CHANGED
@@ -98,6 +98,22 @@ interface SchemaRegistryOptions {
98
98
  * (useful in tests).
99
99
  */
100
100
  multiTenant?: boolean;
101
+ /**
102
+ * Policy for cross-package base-layer metadata collisions (ADR-0048) — two
103
+ * different code packages registering a bare-named generic item under the
104
+ * same `(type, name)`.
105
+ *
106
+ * - `'error'` (default): throw {@link MetadataCollisionError} at registration
107
+ * time, naming both packages and the type/name. Makes the otherwise-silent
108
+ * last-write-wins shadowing a loud, actionable failure.
109
+ * - `'warn'`: log a warning and let the registration proceed. For deliberate
110
+ * migrations where a collision is temporarily expected.
111
+ *
112
+ * Sourced from `OS_METADATA_COLLISION` (`warn` to downgrade) when not set
113
+ * explicitly. Legitimate runtime/DB overlays and same-package reloads are
114
+ * never treated as collisions regardless of this setting.
115
+ */
116
+ collisionPolicy?: 'error' | 'warn';
101
117
  }
102
118
  /**
103
119
  * Augment a registered object with implicit system fields.
@@ -132,6 +148,8 @@ declare class SchemaRegistry {
132
148
  private _logLevel;
133
149
  /** Whether to auto-inject multi-tenant system fields. */
134
150
  private readonly multiTenant;
151
+ /** Cross-package base-layer collision policy (ADR-0048). */
152
+ private readonly collisionPolicy;
135
153
  constructor(options?: SchemaRegistryOptions);
136
154
  get logLevel(): RegistryLogLevel;
137
155
  set logLevel(level: RegistryLogLevel);
@@ -258,6 +276,15 @@ declare class SchemaRegistry {
258
276
  * Universal Register Method for non-object metadata.
259
277
  */
260
278
  registerItem<T>(type: string, item: T, keyField?: keyof T, packageId?: string): void;
279
+ /**
280
+ * Find a code package OTHER than `incoming` that already owns `baseName` in
281
+ * `collection` (ADR-0048 cross-package collision detection). Scans the live
282
+ * collection — like {@link getItem} / {@link unregisterItem} — so it always
283
+ * reflects current state with no parallel index to drift across
284
+ * reset/unregister. Returns the conflicting owner's package id, or undefined
285
+ * when the name is free or only held by the same package / a runtime overlay.
286
+ */
287
+ private findOtherPackageOwner;
261
288
  /**
262
289
  * Validate Metadata against Spec Zod Schemas
263
290
  */
@@ -270,6 +297,38 @@ declare class SchemaRegistry {
270
297
  * Universal Get Method
271
298
  */
272
299
  getItem<T>(type: string, name: string): T | undefined;
300
+ /**
301
+ * Artifact-only lookup (ADR-0010 §3.3). Unlike {@link getItem} — which
302
+ * returns the plain-key entry first, so a runtime/DB-rehydrated row
303
+ * registered under the bare name SHADOWS the packaged artifact — this
304
+ * scans the composite (`<packageId>:<name>`) entries first and only
305
+ * returns an item whose `_packageId` marks a genuine code package
306
+ * (truthy and not the `'sys_metadata'` rehydration sentinel).
307
+ *
308
+ * This is what the protocol's lock/provenance resolution must use:
309
+ * the artifact's `_lock` envelope always wins over an overlay, and an
310
+ * overlay row hydrated into the plain key must never be able to mask
311
+ * it (that masking is exactly the "registry pollution" bug where a
312
+ * locked app's `_lock` read back as undefined after a PUT+GET).
313
+ */
314
+ getArtifactItem<T>(type: string, name: string): T | undefined;
315
+ /**
316
+ * Remove a plain-key runtime shadow so the packaged artifact registered
317
+ * under a composite key becomes the visible value again. Used by the
318
+ * metadata reset path (`deleteMetaItem`): deleting the `sys_metadata`
319
+ * overlay row must also heal the in-memory registry, otherwise the
320
+ * stale overlay copy keeps shadowing the artifact until restart.
321
+ *
322
+ * Deliberately conservative: the plain-key entry is only deleted when a
323
+ * packaged artifact still exists under a composite key, so the name
324
+ * stays resolvable afterwards. A runtime-only item (no artifact
325
+ * backing) is left untouched. Note the plain entry's own `_packageId`
326
+ * is NOT consulted — the hydration path grafts the artifact envelope
327
+ * onto the shadow (ADR-0010 §3.3), so a stamped `_packageId` does not
328
+ * mean the plain entry IS the artifact registration; artifact loaders
329
+ * always register under a composite key.
330
+ */
331
+ removeRuntimeShadow(type: string, name: string): boolean;
273
332
  /**
274
333
  * Universal List Method
275
334
  */
@@ -621,6 +680,8 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
621
680
  method?: "POST" | "PUT" | "DELETE" | "PATCH" | undefined;
622
681
  bodyExtra?: Record<string, unknown> | undefined;
623
682
  mode?: "custom" | "create" | "delete" | "edit" | undefined;
683
+ opensInNewTab?: boolean | undefined;
684
+ newTabUrl?: string | undefined;
624
685
  timeout?: number | undefined;
625
686
  aria?: {
626
687
  ariaLabel?: string | undefined;
@@ -1244,6 +1305,26 @@ declare class ObjectStackProtocolImplementation implements ObjectStackProtocol {
1244
1305
  * stale schema into the registry.
1245
1306
  */
1246
1307
  private applyObjectRegistryMutation;
1308
+ /**
1309
+ * Heal the in-memory registry after a metadata reset (overlay-row
1310
+ * delete) on control-plane kernels. Two layers:
1311
+ *
1312
+ * 1. Drop the plain-key runtime shadow so the packaged artifact
1313
+ * (registered under `<packageId>:<name>`) becomes the visible
1314
+ * value again. The shadow is written by the overlay-hydration
1315
+ * paths (`getMetaItems` / `loadMetaFromDb`) and — pre-fix —
1316
+ * survived the reset until restart, leaving stale overlay
1317
+ * content (and a stripped `_lock` envelope) in every
1318
+ * registry-direct read (ADR-0010 §3.3).
1319
+ * 2. When no composite-key artifact exists, fall back to the
1320
+ * MetadataService baseline (FilesystemLoader-sourced types) and
1321
+ * re-register it, preserving the historical refresh behaviour
1322
+ * for items the SchemaRegistry never held as artifacts.
1323
+ *
1324
+ * Best-effort: a failure must never block the delete that already
1325
+ * succeeded; the next full reload fixes the registry anyway.
1326
+ */
1327
+ private restoreArtifactRegistryView;
1247
1328
  /**
1248
1329
  * Ensure a just-PUBLISHED object's physical table exists so it is usable
1249
1330
  * for data CRUD immediately — without a server restart. Registering the