@adobe/data 0.9.60 → 0.9.61

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.
Files changed (166) hide show
  1. package/dist/ecs/database/combine-plugins.d.ts +5 -1
  2. package/dist/ecs/database/combine-plugins.js +3 -3
  3. package/dist/ecs/database/combine-plugins.js.map +1 -1
  4. package/dist/ecs/database/create-plugin.d.ts +17 -14
  5. package/dist/ecs/database/create-plugin.js +2 -1
  6. package/dist/ecs/database/create-plugin.js.map +1 -1
  7. package/dist/ecs/database/database.d.ts +32 -4
  8. package/dist/ecs/database/database.index.performance.test.d.ts +1 -0
  9. package/dist/ecs/database/database.index.performance.test.js +417 -0
  10. package/dist/ecs/database/database.index.performance.test.js.map +1 -0
  11. package/dist/ecs/database/database.index.test.d.ts +1 -0
  12. package/dist/ecs/database/database.index.test.js +762 -0
  13. package/dist/ecs/database/database.index.test.js.map +1 -0
  14. package/dist/ecs/database/database.index.type-test.d.ts +1 -0
  15. package/dist/ecs/database/database.index.type-test.js +275 -0
  16. package/dist/ecs/database/database.index.type-test.js.map +1 -0
  17. package/dist/ecs/database/database.js.map +1 -1
  18. package/dist/ecs/database/deep-extends-chain.type-test.d.ts +256 -256
  19. package/dist/ecs/database/index-api-proof.type-test.d.ts +1 -0
  20. package/dist/ecs/database/index-api-proof.type-test.js +88 -0
  21. package/dist/ecs/database/index-api-proof.type-test.js.map +1 -0
  22. package/dist/ecs/database/index-registry/create-index-registry.d.ts +53 -0
  23. package/dist/ecs/database/index-registry/create-index-registry.js +174 -0
  24. package/dist/ecs/database/index-registry/create-index-registry.js.map +1 -0
  25. package/dist/ecs/database/index-registry/create-index.d.ts +60 -0
  26. package/dist/ecs/database/index-registry/create-index.js +539 -0
  27. package/dist/ecs/database/index-registry/create-index.js.map +1 -0
  28. package/dist/ecs/database/index-registry/index.d.ts +4 -0
  29. package/dist/ecs/database/index-registry/index.js +4 -0
  30. package/dist/ecs/database/index-registry/index.js.map +1 -0
  31. package/dist/ecs/database/public/create-database.js +146 -0
  32. package/dist/ecs/database/public/create-database.js.map +1 -1
  33. package/dist/ecs/database/transactional-store/transactional-store.d.ts +3 -2
  34. package/dist/ecs/plugins/scheduler/scheduler.d.ts +1 -0
  35. package/dist/ecs/store/index-types.d.ts +132 -0
  36. package/dist/ecs/store/index-types.js +3 -0
  37. package/dist/ecs/store/index-types.js.map +1 -0
  38. package/dist/ecs/store/public/create-store.js +189 -3
  39. package/dist/ecs/store/public/create-store.js.map +1 -1
  40. package/dist/ecs/store/store.d.ts +30 -13
  41. package/dist/ecs/store/store.js +5 -4
  42. package/dist/ecs/store/store.js.map +1 -1
  43. package/dist/ecs/store/transaction-functions.d.ts +4 -3
  44. package/dist/schema/fractional-index/between-n.d.ts +2 -0
  45. package/dist/schema/fractional-index/between-n.js +34 -0
  46. package/dist/schema/fractional-index/between-n.js.map +1 -0
  47. package/dist/schema/fractional-index/between-n.test.d.ts +1 -0
  48. package/dist/schema/fractional-index/between-n.test.js +36 -0
  49. package/dist/schema/fractional-index/between-n.test.js.map +1 -0
  50. package/dist/schema/fractional-index/between.d.ts +2 -0
  51. package/dist/schema/fractional-index/between.js +3 -0
  52. package/dist/schema/fractional-index/between.js.map +1 -0
  53. package/dist/schema/fractional-index/between.test.d.ts +1 -0
  54. package/dist/schema/fractional-index/between.test.js +68 -0
  55. package/dist/schema/fractional-index/between.test.js.map +1 -0
  56. package/dist/schema/fractional-index/decrement-integer.d.ts +1 -0
  57. package/dist/schema/fractional-index/decrement-integer.js +32 -0
  58. package/dist/schema/fractional-index/decrement-integer.js.map +1 -0
  59. package/dist/schema/fractional-index/decrement-integer.test.d.ts +1 -0
  60. package/dist/schema/fractional-index/decrement-integer.test.js +31 -0
  61. package/dist/schema/fractional-index/decrement-integer.test.js.map +1 -0
  62. package/dist/schema/fractional-index/digits.d.ts +1 -0
  63. package/dist/schema/fractional-index/digits.js +3 -0
  64. package/dist/schema/fractional-index/digits.js.map +1 -0
  65. package/dist/schema/fractional-index/fractional-index.d.ts +4 -0
  66. package/dist/schema/fractional-index/fractional-index.js +2 -0
  67. package/dist/schema/fractional-index/fractional-index.js.map +1 -0
  68. package/dist/schema/fractional-index/increment-integer.d.ts +1 -0
  69. package/dist/schema/fractional-index/increment-integer.js +32 -0
  70. package/dist/schema/fractional-index/increment-integer.js.map +1 -0
  71. package/dist/schema/fractional-index/increment-integer.test.d.ts +1 -0
  72. package/dist/schema/fractional-index/increment-integer.test.js +34 -0
  73. package/dist/schema/fractional-index/increment-integer.test.js.map +1 -0
  74. package/dist/schema/fractional-index/initial.d.ts +2 -0
  75. package/dist/schema/fractional-index/initial.js +2 -0
  76. package/dist/schema/fractional-index/initial.js.map +1 -0
  77. package/dist/schema/fractional-index/integer-length.d.ts +1 -0
  78. package/dist/schema/fractional-index/integer-length.js +9 -0
  79. package/dist/schema/fractional-index/integer-length.js.map +1 -0
  80. package/dist/schema/fractional-index/integer-part.d.ts +1 -0
  81. package/dist/schema/fractional-index/integer-part.js +9 -0
  82. package/dist/schema/fractional-index/integer-part.js.map +1 -0
  83. package/dist/schema/fractional-index/key-between.d.ts +2 -0
  84. package/dist/schema/fractional-index/key-between.js +39 -0
  85. package/dist/schema/fractional-index/key-between.js.map +1 -0
  86. package/dist/schema/fractional-index/midpoint.d.ts +1 -0
  87. package/dist/schema/fractional-index/midpoint.js +23 -0
  88. package/dist/schema/fractional-index/midpoint.js.map +1 -0
  89. package/dist/schema/fractional-index/midpoint.test.d.ts +1 -0
  90. package/dist/schema/fractional-index/midpoint.test.js +83 -0
  91. package/dist/schema/fractional-index/midpoint.test.js.map +1 -0
  92. package/dist/schema/fractional-index/public.d.ts +4 -0
  93. package/dist/schema/fractional-index/public.js +6 -0
  94. package/dist/schema/fractional-index/public.js.map +1 -0
  95. package/dist/schema/fractional-index/schema.d.ts +4 -0
  96. package/dist/schema/fractional-index/schema.js +5 -0
  97. package/dist/schema/fractional-index/schema.js.map +1 -0
  98. package/dist/schema/fractional-index/smallest-integer.d.ts +1 -0
  99. package/dist/schema/fractional-index/smallest-integer.js +3 -0
  100. package/dist/schema/fractional-index/smallest-integer.js.map +1 -0
  101. package/dist/schema/fractional-index/validate-integer.d.ts +1 -0
  102. package/dist/schema/fractional-index/validate-integer.js +7 -0
  103. package/dist/schema/fractional-index/validate-integer.js.map +1 -0
  104. package/dist/schema/fractional-index/validate-order-key.d.ts +1 -0
  105. package/dist/schema/fractional-index/validate-order-key.js +11 -0
  106. package/dist/schema/fractional-index/validate-order-key.js.map +1 -0
  107. package/dist/schema/guid/create.d.ts +2 -0
  108. package/dist/schema/guid/create.js +10 -0
  109. package/dist/schema/guid/create.js.map +1 -0
  110. package/dist/schema/guid/create.test.d.ts +1 -0
  111. package/dist/schema/guid/create.test.js +39 -0
  112. package/dist/schema/guid/create.test.js.map +1 -0
  113. package/dist/schema/guid/equals.d.ts +2 -0
  114. package/dist/schema/guid/equals.js +3 -0
  115. package/dist/schema/guid/equals.js.map +1 -0
  116. package/dist/schema/guid/equals.test.d.ts +1 -0
  117. package/dist/schema/guid/equals.test.js +30 -0
  118. package/dist/schema/guid/equals.test.js.map +1 -0
  119. package/dist/schema/guid/from-uuid.d.ts +2 -0
  120. package/dist/schema/guid/from-uuid.js +15 -0
  121. package/dist/schema/guid/from-uuid.js.map +1 -0
  122. package/dist/schema/guid/from-uuid.test.d.ts +1 -0
  123. package/dist/schema/guid/from-uuid.test.js +39 -0
  124. package/dist/schema/guid/from-uuid.test.js.map +1 -0
  125. package/dist/schema/guid/guid.performance.test.d.ts +1 -0
  126. package/dist/schema/guid/guid.performance.test.js +297 -0
  127. package/dist/schema/guid/guid.performance.test.js.map +1 -0
  128. package/dist/schema/guid/index.d.ts +4 -0
  129. package/dist/schema/guid/index.js +3 -0
  130. package/dist/schema/guid/index.js.map +1 -0
  131. package/dist/schema/guid/layout.d.ts +1 -0
  132. package/dist/schema/guid/layout.js +5 -0
  133. package/dist/schema/guid/layout.js.map +1 -0
  134. package/dist/schema/guid/nil.d.ts +2 -0
  135. package/dist/schema/guid/nil.js +3 -0
  136. package/dist/schema/guid/nil.js.map +1 -0
  137. package/dist/schema/guid/public.d.ts +8 -0
  138. package/dist/schema/guid/public.js +10 -0
  139. package/dist/schema/guid/public.js.map +1 -0
  140. package/dist/schema/guid/schema.d.ts +12 -0
  141. package/dist/schema/guid/schema.js +10 -0
  142. package/dist/schema/guid/schema.js.map +1 -0
  143. package/dist/schema/guid/schema.test.d.ts +1 -0
  144. package/dist/schema/guid/schema.test.js +35 -0
  145. package/dist/schema/guid/schema.test.js.map +1 -0
  146. package/dist/schema/guid/to-unserializable-key.d.ts +2 -0
  147. package/dist/schema/guid/to-unserializable-key.js +10 -0
  148. package/dist/schema/guid/to-unserializable-key.js.map +1 -0
  149. package/dist/schema/guid/to-uuid.d.ts +2 -0
  150. package/dist/schema/guid/to-uuid.js +15 -0
  151. package/dist/schema/guid/to-uuid.js.map +1 -0
  152. package/dist/schema/guid/to-uuid.test.d.ts +1 -0
  153. package/dist/schema/guid/to-uuid.test.js +31 -0
  154. package/dist/schema/guid/to-uuid.test.js.map +1 -0
  155. package/dist/schema/index.d.ts +2 -0
  156. package/dist/schema/index.js +2 -0
  157. package/dist/schema/index.js.map +1 -1
  158. package/dist/table/select-rows.d.ts +7 -4
  159. package/dist/table/select-rows.js.map +1 -1
  160. package/dist/tsconfig.tsbuildinfo +1 -1
  161. package/package.json +1 -1
  162. package/references/data-lit/package.json +1 -1
  163. package/references/data-lit-tictactoe/package.json +1 -1
  164. package/references/data-react/package.json +1 -1
  165. package/references/data-react-hello/package.json +1 -1
  166. package/references/data-react-pixie/package.json +1 -1
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,88 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ // ============================================================================
3
+ // 1. Single-column unique lookup — `byEmail`
4
+ // ============================================================================
5
+ {
6
+ }
7
+ // ============================================================================
8
+ // 2. Multi-column compound unique — `playerSlot`
9
+ // ============================================================================
10
+ {
11
+ }
12
+ // ============================================================================
13
+ // 3. Non-unique by single column — `childrenOf`
14
+ // ============================================================================
15
+ {
16
+ }
17
+ // ============================================================================
18
+ // 4. Sorted children — `orderedChildrenOf`
19
+ // ============================================================================
20
+ {
21
+ }
22
+ // ============================================================================
23
+ // 5. Multi-value (array column → fan-out) — `tasksByAssignee`
24
+ // ============================================================================
25
+ {
26
+ }
27
+ // ============================================================================
28
+ // 6. Computed scalar (case-insensitive email) — `byEmailCi`
29
+ // ============================================================================
30
+ {
31
+ }
32
+ // ============================================================================
33
+ // 7. Multi-value computed (compute returns array → fan-out) — `docsByKeyword`
34
+ // ============================================================================
35
+ {
36
+ }
37
+ // ============================================================================
38
+ // 8. Compound from nested data — `playerByRoster`
39
+ // ============================================================================
40
+ {
41
+ }
42
+ // ============================================================================
43
+ // 9. Sorted from nested data — `orderedChildrenOfFoo`
44
+ // ============================================================================
45
+ {
46
+ }
47
+ // ============================================================================
48
+ // 10. Mixed identity + derived parts — `playerByTeamRole`
49
+ // ============================================================================
50
+ {
51
+ }
52
+ // ============================================================================
53
+ // 11. Computed mapped + sorted — `orderedRoster`
54
+ // ============================================================================
55
+ {
56
+ }
57
+ // ============================================================================
58
+ // 12. Custom comparator — `tasksByPriority`
59
+ // ============================================================================
60
+ {
61
+ }
62
+ // ============================================================================
63
+ // NEGATIVE TYPE CHECKS — these declarations should fail to typecheck.
64
+ // ============================================================================
65
+ {
66
+ }
67
+ {
68
+ }
69
+ {
70
+ // @ts-expect-error - "bogus" is not a column on C
71
+ const _decl = { team: "team", role: "bogus" };
72
+ void _decl;
73
+ }
74
+ {
75
+ const goodCompare = (a, b) => a.fractIndex.localeCompare(b.fractIndex);
76
+ void goodCompare;
77
+ // Reading an undeclared column inside compare is a compile error.
78
+ const badCompare = (a, b) =>
79
+ // @ts-expect-error - `priority` is not in `Pick<C, "fractIndex">`
80
+ a.priority - b.priority;
81
+ void badCompare;
82
+ }
83
+ {
84
+ }
85
+ {
86
+ }
87
+ export {};
88
+ //# sourceMappingURL=index-api-proof.type-test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-api-proof.type-test.js","sourceRoot":"","sources":["../../../src/ecs/database/index-api-proof.type-test.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAkGvD,+EAA+E;AAC/E,6CAA6C;AAC7C,+EAA+E;AAE/E,CAAC;AAQD,CAAC;AAED,+EAA+E;AAC/E,iDAAiD;AACjD,+EAA+E;AAE/E,CAAC;AASD,CAAC;AAED,+EAA+E;AAC/E,gDAAgD;AAChD,+EAA+E;AAE/E,CAAC;AAOD,CAAC;AAED,+EAA+E;AAC/E,2CAA2C;AAC3C,+EAA+E;AAE/E,CAAC;AASD,CAAC;AAED,+EAA+E;AAC/E,8DAA8D;AAC9D,+EAA+E;AAE/E,CAAC;AAMD,CAAC;AAED,+EAA+E;AAC/E,4DAA4D;AAC5D,+EAA+E;AAE/E,CAAC;AAKD,CAAC;AAED,+EAA+E;AAC/E,8EAA8E;AAC9E,+EAA+E;AAE/E,CAAC;AAMD,CAAC;AAED,+EAA+E;AAC/E,kDAAkD;AAClD,+EAA+E;AAE/E,CAAC;AAeD,CAAC;AAED,+EAA+E;AAC/E,sDAAsD;AACtD,+EAA+E;AAE/E,CAAC;AAYD,CAAC;AAED,+EAA+E;AAC/E,0DAA0D;AAC1D,+EAA+E;AAE/E,CAAC;AAcD,CAAC;AAED,+EAA+E;AAC/E,iDAAiD;AACjD,+EAA+E;AAE/E,CAAC;AAmBD,CAAC;AAED,+EAA+E;AAC/E,4CAA4C;AAC5C,+EAA+E;AAE/E,CAAC;AAeD,CAAC;AAED,+EAA+E;AAC/E,sEAAsE;AACtE,+EAA+E;AAE/E,CAAC;AAID,CAAC;AAED,CAAC;AAOD,CAAC;AAED,CAAC;IAMG,kDAAkD;IAClD,MAAM,KAAK,GAAY,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACvD,KAAK,KAAK,CAAC;AACf,CAAC;AAED,CAAC;IAMG,MAAM,WAAW,GAAqB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IACzF,KAAK,WAAW,CAAC;IAEjB,kEAAkE;IAClE,MAAM,UAAU,GAAqB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;IAC1C,kEAAkE;IAClE,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;IAC5B,KAAK,UAAU,CAAC;AACpB,CAAC;AAED,CAAC;AAID,CAAC;AAED,CAAC;AAQD,CAAC"}
@@ -0,0 +1,53 @@
1
+ import type { Entity } from "../../entity/entity.js";
2
+ import type { TransactionResult } from "../transactional-store/index.js";
3
+ import { IndexKeyDecl, IndexOrderDecl, RuntimeIndex } from "./create-index.js";
4
+ /**
5
+ * Reads the post-transaction values of an entity, or returns null when the
6
+ * entity does not exist. Supplied by `createStore` so the registry stays
7
+ * decoupled from the store layer.
8
+ */
9
+ export type EntityReader = (entity: Entity) => Readonly<Record<string, unknown>> | null;
10
+ /**
11
+ * Plugin-level declaration object as it appears in `plugin.indexes[name]`.
12
+ * The registry holds the *exact* reference so the same-name re-registration
13
+ * check can compare identity (`===`) — matching the rule
14
+ * `combinePlugins` already enforces for components / transactions / etc.
15
+ *
16
+ * Mirrors the public `Index` type from `store/index-types.ts` at the
17
+ * value layer (the registry doesn't have access to the host component
18
+ * map, so this version is loose-typed).
19
+ */
20
+ export type IndexDeclarationObject = {
21
+ readonly key: IndexKeyDecl;
22
+ readonly order?: IndexOrderDecl;
23
+ readonly unique?: boolean;
24
+ readonly components?: readonly string[];
25
+ };
26
+ export interface IndexRegistry {
27
+ readonly indexes: ReadonlyMap<string, RuntimeIndex>;
28
+ /**
29
+ * Registers a new index from its plugin declaration object.
30
+ *
31
+ * - Same `name` with identity-equal `decl`: no-op (returns null).
32
+ * - Same `name` with a different `decl` object: throws.
33
+ * - Different `name` with structurally identical declaration: throws.
34
+ *
35
+ * Returns the new `RuntimeIndex` for the caller to seed from archetypes.
36
+ */
37
+ register(name: string, decl: IndexDeclarationObject): RuntimeIndex | null;
38
+ /** Apply a transaction's changes to every registered index. */
39
+ apply(result: TransactionResult<any>): void;
40
+ /** Drop all bucket entries without reseeding. */
41
+ clear(): void;
42
+ /** Reflect a single insert. Throws on unique conflict — pre-check first. */
43
+ applyInsert(entity: Entity, values: Readonly<Record<string, unknown>>): void;
44
+ /** Reflect a single update by re-reading the entity's full values. */
45
+ applyUpdate(entity: Entity): void;
46
+ /** Reflect a single delete. */
47
+ applyDelete(entity: Entity): void;
48
+ /** Throws if any unique index would collide. Call before mutating. */
49
+ checkUniqueAvailableForInsert(values: Readonly<Record<string, unknown>>): void;
50
+ /** Like the insert version, but excludes self-collisions for `entity`. */
51
+ checkUniqueAvailableForUpdate(entity: Entity, patch: Readonly<Record<string, unknown>>): void;
52
+ }
53
+ export declare const createIndexRegistry: (read: EntityReader) => IndexRegistry;
@@ -0,0 +1,174 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ import { createIndex } from "./create-index.js";
3
+ /**
4
+ * Assigns a stable numeric id to each distinct function the registry sees
5
+ * (used inside the structural-duplicate shape key). Two indexes with the
6
+ * same key shape but different extractor functions are NOT duplicates.
7
+ */
8
+ const fnIds = new WeakMap();
9
+ let nextFnId = 0;
10
+ const fnIdent = (fn) => {
11
+ let id = fnIds.get(fn);
12
+ if (id === undefined) {
13
+ id = nextFnId++;
14
+ fnIds.set(fn, id);
15
+ }
16
+ return `f${id}`;
17
+ };
18
+ const keyIdent = (key) => {
19
+ if (typeof key === "string")
20
+ return `s:${key}`;
21
+ if (Array.isArray(key))
22
+ return `t:${key.join("\x1f")}`;
23
+ if (typeof key === "function")
24
+ return `f:${fnIdent(key)}`;
25
+ // Slot map — sort slot names for stable ordering.
26
+ const slots = Object.entries(key).sort();
27
+ return "m:" + slots.map(([slot, v]) => typeof v === "string" ? `${slot}=s:${v}` : `${slot}=${fnIdent(v)}`).join("\x1f");
28
+ };
29
+ const orderIdent = (order) => {
30
+ if (!order)
31
+ return "";
32
+ const by = order.by.join("\x1f");
33
+ const cmp = order.compare ? fnIdent(order.compare) : "default";
34
+ return `${by}|${cmp}`;
35
+ };
36
+ const shapeKey = (decl) => [
37
+ decl.unique ?? false,
38
+ keyIdent(decl.key),
39
+ orderIdent(decl.order),
40
+ ].join("\x1f");
41
+ const formatShape = (decl) => {
42
+ const unique = decl.unique ? " unique" : "";
43
+ const order = decl.order ? ` order=[${decl.order.by.join(",")}]` : "";
44
+ return `key=${keyIdent(decl.key)}${unique}${order}`;
45
+ };
46
+ export const createIndexRegistry = (read) => {
47
+ const indexes = new Map();
48
+ const entries = new Map();
49
+ const shapeToName = new Map();
50
+ const register = (name, decl) => {
51
+ const existing = entries.get(name);
52
+ if (existing) {
53
+ if (existing.decl === decl)
54
+ return null;
55
+ throw new Error(`Index "${name}" already registered with a different declaration object. ` +
56
+ `Indexes must reuse the same declaration reference across plugins. ` +
57
+ `existing ${formatShape(existing.decl)}, new ${formatShape(decl)}`);
58
+ }
59
+ const sk = shapeKey(decl);
60
+ const dupName = shapeToName.get(sk);
61
+ if (dupName !== undefined) {
62
+ throw new Error(`Indexes "${dupName}" and "${name}" have identical shape ` +
63
+ `(${formatShape(decl)}). Almost certainly an unintentional ` +
64
+ `duplicate — collapse them to a single declaration.`);
65
+ }
66
+ const state = {
67
+ key: decl.key,
68
+ order: decl.order,
69
+ unique: decl.unique ?? false,
70
+ components: decl.components,
71
+ };
72
+ const idx = createIndex(state);
73
+ indexes.set(name, idx);
74
+ entries.set(name, { decl, index: idx });
75
+ shapeToName.set(sk, name);
76
+ return idx;
77
+ };
78
+ const reflectEntity = (entity, change) => {
79
+ if (change === null) {
80
+ for (const idx of indexes.values())
81
+ idx.remove(entity);
82
+ return;
83
+ }
84
+ const values = read(entity);
85
+ if (values === null) {
86
+ for (const idx of indexes.values())
87
+ idx.remove(entity);
88
+ return;
89
+ }
90
+ for (const idx of indexes.values())
91
+ idx.update(entity, values);
92
+ };
93
+ const apply = (result) => {
94
+ if (indexes.size === 0)
95
+ return;
96
+ for (const [entity, change] of result.changedEntities) {
97
+ reflectEntity(entity, change);
98
+ }
99
+ };
100
+ const clear = () => {
101
+ for (const idx of indexes.values())
102
+ idx.clear();
103
+ };
104
+ const applyInsert = (entity, values) => {
105
+ if (indexes.size === 0)
106
+ return;
107
+ for (const idx of indexes.values())
108
+ idx.add(entity, values);
109
+ };
110
+ const applyUpdate = (entity) => {
111
+ if (indexes.size === 0)
112
+ return;
113
+ const values = read(entity);
114
+ if (values === null) {
115
+ for (const idx of indexes.values())
116
+ idx.remove(entity);
117
+ return;
118
+ }
119
+ for (const idx of indexes.values())
120
+ idx.update(entity, values);
121
+ };
122
+ const applyDelete = (entity) => {
123
+ if (indexes.size === 0)
124
+ return;
125
+ for (const idx of indexes.values())
126
+ idx.remove(entity);
127
+ };
128
+ const checkUniqueAvailableForInsert = (values) => {
129
+ for (const [name, idx] of indexes) {
130
+ if (!idx.unique)
131
+ continue;
132
+ const collidesWith = idx.checkUniqueAvailable(values, null);
133
+ if (collidesWith !== null) {
134
+ throw new Error(`Unique index conflict on "${name}": existing entity ${collidesWith}.`);
135
+ }
136
+ }
137
+ };
138
+ const checkUniqueAvailableForUpdate = (entity, patch) => {
139
+ let hasUnique = false;
140
+ for (const idx of indexes.values()) {
141
+ if (idx.unique) {
142
+ hasUnique = true;
143
+ break;
144
+ }
145
+ }
146
+ if (!hasUnique)
147
+ return;
148
+ const current = read(entity);
149
+ if (current === null)
150
+ return;
151
+ const effective = { ...current, ...patch };
152
+ for (const [name, idx] of indexes) {
153
+ if (!idx.unique)
154
+ continue;
155
+ const collidesWith = idx.checkUniqueAvailable(effective, entity);
156
+ if (collidesWith !== null) {
157
+ throw new Error(`Unique index conflict on "${name}": existing entity ${collidesWith} ` +
158
+ `would collide with the update of entity ${entity}.`);
159
+ }
160
+ }
161
+ };
162
+ return {
163
+ indexes,
164
+ register,
165
+ apply,
166
+ clear,
167
+ applyInsert,
168
+ applyUpdate,
169
+ applyDelete,
170
+ checkUniqueAvailableForInsert,
171
+ checkUniqueAvailableForUpdate,
172
+ };
173
+ };
174
+ //# sourceMappingURL=create-index-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-index-registry.js","sourceRoot":"","sources":["../../../../src/ecs/database/index-registry/create-index-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import type { Entity } from "../../entity/entity.js";
2
+ /**
3
+ * `key` declaration variants. See `Index` in `store/index-types.ts` for
4
+ * the type-level mirror that drives `find` / `get` argument inference.
5
+ */
6
+ export type IndexKeyDecl = string | readonly string[] | ((...args: any[]) => unknown) | {
7
+ readonly [slot: string]: string | ((...args: any[]) => unknown);
8
+ };
9
+ /** `order` declaration: read columns + optional comparator. */
10
+ export type IndexOrderDecl = {
11
+ readonly by: readonly string[];
12
+ readonly compare?: (a: any, b: any) => number;
13
+ };
14
+ /**
15
+ * The shape a user (or higher layer) hands to `createIndex` for a single
16
+ * index. Mirrors the public `Index` type but loose-typed at this layer
17
+ * because the runtime doesn't have access to the host component map.
18
+ */
19
+ export interface IndexState {
20
+ readonly key: IndexKeyDecl;
21
+ readonly order?: IndexOrderDecl;
22
+ readonly unique?: boolean;
23
+ /**
24
+ * Columns extractor functions read. Only required when at least one
25
+ * function in `key` reads from a column not already covered by a
26
+ * string identity in `key` or `order.by`.
27
+ */
28
+ readonly components?: readonly string[];
29
+ }
30
+ /**
31
+ * Runtime instance of a single declared index. Public methods mirror
32
+ * `Index.Handle` in `store/index-types.ts`.
33
+ */
34
+ export interface RuntimeIndex {
35
+ readonly unique: boolean;
36
+ /** Columns the index reads from entities, for the store-layer seed path. */
37
+ readonly readColumns: readonly string[];
38
+ /** Whether this index is sorted (`order` was declared). */
39
+ readonly sorted: boolean;
40
+ /** Underlying key declaration — exposed for the auto-router and dedup. */
41
+ readonly key: IndexKeyDecl;
42
+ /** Underlying order declaration, if any. */
43
+ readonly order: IndexOrderDecl | undefined;
44
+ add(entity: Entity, values: Readonly<Record<string, unknown>>): void;
45
+ remove(entity: Entity): void;
46
+ update(entity: Entity, values: Readonly<Record<string, unknown>>): void;
47
+ clear(): void;
48
+ readonly size: number;
49
+ find(arg: unknown): readonly Entity[];
50
+ findRange(arg: unknown): readonly Entity[];
51
+ get(arg: unknown): Entity | null;
52
+ /**
53
+ * For unique indexes: returns the existing entity holding any bucket
54
+ * key the new `values` would land in (excluding `excludeEntity` if
55
+ * provided), or null. Used by the Store-layer pre-check so unique
56
+ * conflicts throw before the column mutation.
57
+ */
58
+ checkUniqueAvailable(values: Readonly<Record<string, unknown>>, excludeEntity: Entity | null): Entity | null;
59
+ }
60
+ export declare const createIndex: (state: IndexState) => RuntimeIndex;