@adobe/data 0.9.65 → 0.9.67

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.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ import { createPlugin } from "./create-plugin.js";
3
+ /**
4
+ * Type-only tests for naming archetype rows without a cast.
5
+ *
6
+ * The regression these guard against: a consumer who exposes
7
+ * `db.archetypes.Track` under a hand-authored service interface used to need
8
+ * `as unknown as` at every boundary. The fix is to *derive* the service type
9
+ * from the plugin and *name* rows with `Database.Archetype.RowOf` rather than
10
+ * re-spelling their columns. These are compile-time checks only.
11
+ */
12
+ const trackPlugin = createPlugin({
13
+ components: {
14
+ trackKind: { type: "string" },
15
+ editingMode: { type: "string" },
16
+ muted: { type: "boolean" },
17
+ },
18
+ archetypes: {
19
+ Track: ["trackKind", "editingMode", "muted"],
20
+ },
21
+ });
22
+ // 1. `db.archetypes` assigns to the derived service's archetype map with NO cast.
23
+ const archetypes = db.archetypes;
24
+ void archetypes;
25
+ // 3. A named row round-trips: `ReadonlyArchetype<RowOf<...>>` accepts the handle
26
+ // with no cast, because it is structurally the same archetype.
27
+ const track = db.archetypes.Track;
28
+ void track;
29
+ const observed = db.observe.entity(someEntity, db.archetypes.Track);
30
+ void observed;
31
+ //# sourceMappingURL=archetype-row.type-test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"archetype-row.type-test.js","sourceRoot":"","sources":["../../../src/ecs/database/archetype-row.type-test.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AASlD;;;;;;;;GAQG;AAEH,MAAM,WAAW,GAAG,YAAY,CAAC;IAC7B,UAAU,EAAE;QACR,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC7B,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAC/B,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;KAC7B;IACD,UAAU,EAAE;QACR,KAAK,EAAE,CAAC,WAAW,EAAE,aAAa,EAAE,OAAO,CAAC;KAC/C;CACJ,CAAC,CAAC;AAOH,kFAAkF;AAClF,MAAM,UAAU,GAA8B,EAAE,CAAC,UAAU,CAAC;AAC5D,KAAK,UAAU,CAAC;AAWhB,iFAAiF;AACjF,kEAAkE;AAClE,MAAM,KAAK,GAAgC,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;AAC/D,KAAK,KAAK,CAAC;AAMX,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AAGpE,KAAK,QAAQ,CAAC"}
@@ -1,7 +1,8 @@
1
- import { Simplify, StringKeyof } from "../../types/types.js";
1
+ import { StringKeyof, UnionToIntersection } from "../../types/types.js";
2
2
  import type { Database } from "./database.js";
3
- type IntersectAll<T extends readonly unknown[]> = Simplify<T extends readonly [infer H, ...infer R] ? H & IntersectAll<R> : unknown>;
4
- type UnionAll<T extends readonly unknown[]> = Simplify<T extends readonly [infer H, ...infer R] ? H | UnionAll<R> : never>;
3
+ type IntersectAll<T extends readonly unknown[]> = [
4
+ T[number]
5
+ ] extends [never] ? unknown : UnionToIntersection<T[number]>;
5
6
  export type CombinePlugins<Plugins extends readonly Database.Plugin[]> = Database.Plugin<{} & IntersectAll<{
6
7
  [K in keyof Plugins]: Plugins[K]['components'];
7
8
  }>, {} & IntersectAll<{
@@ -10,9 +11,9 @@ export type CombinePlugins<Plugins extends readonly Database.Plugin[]> = Databas
10
11
  [K in keyof Plugins]: Plugins[K]['archetypes'];
11
12
  }>, {} & IntersectAll<{
12
13
  [K in keyof Plugins]: Plugins[K]['transactions'];
13
- }>, Extract<UnionAll<{
14
+ }>, Extract<{
14
15
  [K in keyof Plugins]: StringKeyof<Plugins[K]['systems']>;
15
- }>, string>, {} & IntersectAll<{
16
+ }[number], string>, {} & IntersectAll<{
16
17
  [K in keyof Plugins]: Plugins[K]['actions'];
17
18
  }>, {} & IntersectAll<{
18
19
  [K in keyof Plugins]: Plugins[K]['services'];
@@ -37,9 +38,9 @@ export declare function combinePlugins<const Plugins extends readonly Database.P
37
38
  [K in keyof Plugins]: Plugins[K]['archetypes'];
38
39
  }>, {} & IntersectAll<{
39
40
  [K in keyof Plugins]: Plugins[K]['transactions'];
40
- }>, Extract<UnionAll<{
41
+ }>, Extract<{
41
42
  [K in keyof Plugins]: StringKeyof<Plugins[K]['systems']>;
42
- }>, string>, {} & IntersectAll<{
43
+ }[number], string>, {} & IntersectAll<{
43
44
  [K in keyof Plugins]: Plugins[K]['actions'];
44
45
  }>, {} & IntersectAll<{
45
46
  [K in keyof Plugins]: Plugins[K]['services'];
@@ -1 +1 @@
1
- {"version":3,"file":"combine-plugins.js","sourceRoot":"","sources":["../../../src/ecs/database/combine-plugins.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAiCvD;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAE5B,GAAG,OAAgB;IAWnB,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,CAAU,CAAC;IAEzI,MAAM,KAAK,GAAG,CAAC,IAAS,EAAE,IAAS,EAAE,EAAE,CACrC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAEhC,wCAAwC;QACxC,MAAM,MAAM,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC;QAC9B,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7C,IAAI,CAAC,IAAI,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrC,MAAM,IAAI,KAAK,CACb,4BAA4B,GAAG,IAAI,CAAC,yCAAyC,CAC9E,CAAC;YACJ,CAAC;YACD,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC,CAAC;IAEN,MAAM,WAAW,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAE3J,6BAA6B;IAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAElD,OAAO,MAAiC,CAAC;AAC3C,CAAC"}
1
+ {"version":3,"file":"combine-plugins.js","sourceRoot":"","sources":["../../../src/ecs/database/combine-plugins.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAoCvD;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAE5B,GAAG,OAAgB;IAWnB,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,CAAU,CAAC;IAEzI,MAAM,KAAK,GAAG,CAAC,IAAS,EAAE,IAAS,EAAE,EAAE,CACrC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAEhC,wCAAwC;QACxC,MAAM,MAAM,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC;QAC9B,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7C,IAAI,CAAC,IAAI,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrC,MAAM,IAAI,KAAK,CACb,4BAA4B,GAAG,IAAI,CAAC,yCAAyC,CAC9E,CAAC;YACJ,CAAC;YACD,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC,CAAC;IAEN,MAAM,WAAW,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAE3J,6BAA6B;IAC7B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAElD,OAAO,MAAiC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,37 @@
1
+ // © 2026 Adobe. MIT License. See /LICENSE for details.
2
+ import { createPlugin } from "./create-plugin.js";
3
+ import { Database } from "./database.js";
4
+ /**
5
+ * Type-only test: `Database.Plugin.combine` resolves correctly over a wide
6
+ * single call.
7
+ *
8
+ * `IntersectAll` was reformulated from linear recursion (`Simplify<H & ...>`)
9
+ * to `UnionToIntersection` over the element union, so instantiation depth is
10
+ * now constant regardless of plugin count and the per-level `Simplify`
11
+ * re-materialization is gone (a ~29% instantiation drop on a 24-plugin combine
12
+ * measured locally). This guards that a wide single combine still produces the
13
+ * correct merged plugin type — the buckets from the first and last plugins are
14
+ * both present, and the result builds into a usable database.
15
+ */
16
+ const p00 = createPlugin({ components: { c00: { type: "number" } }, archetypes: { A00: ["c00"] } });
17
+ const p01 = createPlugin({ components: { c01: { type: "number" } }, archetypes: { A01: ["c01"] } });
18
+ const p02 = createPlugin({ components: { c02: { type: "number" } }, archetypes: { A02: ["c02"] } });
19
+ const p03 = createPlugin({ components: { c03: { type: "number" } }, archetypes: { A03: ["c03"] } });
20
+ const p04 = createPlugin({ components: { c04: { type: "number" } }, archetypes: { A04: ["c04"] } });
21
+ const p05 = createPlugin({ components: { c05: { type: "number" } }, archetypes: { A05: ["c05"] } });
22
+ const p06 = createPlugin({ components: { c06: { type: "number" } }, archetypes: { A06: ["c06"] } });
23
+ const p07 = createPlugin({ components: { c07: { type: "number" } }, archetypes: { A07: ["c07"] } });
24
+ const p08 = createPlugin({ components: { c08: { type: "number" } }, archetypes: { A08: ["c08"] } });
25
+ const p09 = createPlugin({ components: { c09: { type: "number" } }, archetypes: { A09: ["c09"] } });
26
+ const p10 = createPlugin({ components: { c10: { type: "number" } }, archetypes: { A10: ["c10"] } });
27
+ const p11 = createPlugin({ components: { c11: { type: "number" } }, archetypes: { A11: ["c11"] } });
28
+ const p12 = createPlugin({ components: { c12: { type: "number" } }, archetypes: { A12: ["c12"] } });
29
+ const p13 = createPlugin({ components: { c13: { type: "number" } }, archetypes: { A13: ["c13"] } });
30
+ const p14 = createPlugin({ components: { c14: { type: "number" } }, archetypes: { A14: ["c14"] } });
31
+ const p15 = createPlugin({ components: { c15: { type: "number" } }, archetypes: { A15: ["c15"] } });
32
+ const wide = Database.Plugin.combine(p00, p01, p02, p03, p04, p05, p06, p07, p08, p09, p10, p11, p12, p13, p14, p15);
33
+ // And it is still a usable database: building it and reading the merged
34
+ // archetype map type-checks.
35
+ const wideDb = Database.create(wide);
36
+ void wideDb;
37
+ //# sourceMappingURL=combine-plugins.type-test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"combine-plugins.type-test.js","sourceRoot":"","sources":["../../../src/ecs/database/combine-plugins.type-test.ts"],"names":[],"mappings":"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"}
@@ -64,7 +64,7 @@ type CreatePluginResult<XP extends Database.Plugin, CS, RS, A, TD, S extends str
64
64
  *
65
65
  * @throws Error if properties are not in the correct order
66
66
  */
67
- type FullDBForPlugin<CS, RS, A, TD, S extends string, AD, XP extends Database.Plugin, SVF extends ServiceFactories<Database.FromPlugin<XP>>> = Database<FromSchemas<CS & XP['components']>, FromSchemas<RS & XP['resources']>, A & XP['archetypes'], ToTransactionFunctions<TD & XP['transactions']>, S | StringKeyof<XP['systems']>, ToActionFunctions<AD & XP['actions']>, FromServiceFactories<RemoveIndex<SVF> & XP['services']>>;
67
+ type FullDBForPlugin<CS, RS, A, TD, S extends string, AD, XP extends Database.Plugin, SVF extends ServiceFactories<Database.FromPlugin<XP>>, IX = {}> = Database<FromSchemas<CS & XP['components']>, FromSchemas<RS & XP['resources']>, A & XP['archetypes'], ToTransactionFunctions<TD & XP['transactions']>, S | StringKeyof<XP['systems']>, ToActionFunctions<AD & XP['actions']>, FromServiceFactories<RemoveIndex<SVF> & XP['services']>, unknown, IX & XP['indexes']>;
68
68
  /**
69
69
  * Ambient plugin context used for *parameter typing only*: the union of the
70
70
  * `extends` base (XP) and the `imports` dependencies (IP).
@@ -83,7 +83,7 @@ type FullDBForPlugin<CS, RS, A, TD, S extends string, AD, XP extends Database.Pl
83
83
  * `& {}` (identity on the object-typed buckets) — no cost or behavior change.
84
84
  */
85
85
  type AmbientPlugin<XP extends Database.Plugin, IP extends Database.Plugin> = Database.Plugin<XP['components'] & IP['components'], XP['resources'] & IP['resources'], XP['archetypes'] & IP['archetypes'], XP['transactions'] & IP['transactions'], StringKeyof<XP['systems']> | StringKeyof<IP['systems']>, XP['actions'] & IP['actions'], XP['services'] & IP['services'], XP['computed'] & IP['computed'], XP['indexes'] & IP['indexes']>;
86
- export declare function createPlugin<const XP extends Database.Plugin<{}, {}, {}, {}, never, {}, {}, {}, {}>, const IP extends Database.Plugin<{}, {}, {}, {}, never, {}, {}, {}, {}>, const CS extends ComponentSchemas, const RS extends ResourceSchemas, const A extends ArchetypeComponents<StringKeyof<RemoveIndex<CS> & XP['components'] & IP['components']>>, const IX extends IndexDeclarations<FromSchemas<RemoveIndex<CS> & XP['components'] & IP['components']>, RemoveIndex<A> & XP['archetypes'] & IP['archetypes']>, const TD extends TransactionDeclarations<FromSchemas<RemoveIndex<CS> & XP['components'] & IP['components']>, FromSchemas<RemoveIndex<RS> & XP['resources'] & IP['resources']>, RemoveIndex<A> & XP['archetypes'] & IP['archetypes'], RemoveIndex<IX> & XP['indexes'] & IP['indexes']>, const AD, const S extends string = never, const SVF extends ServiceFactories<Database.FromPlugin<AmbientPlugin<XP, IP>>> = {}, const CVF extends PluginComputedFactories<FullDBForPlugin<RemoveIndex<CS>, RemoveIndex<RS>, RemoveIndex<A>, RemoveIndex<TD>, S, RemoveIndex<AD> & XP['actions'] & IP['actions'], AmbientPlugin<XP, IP>, RemoveIndex<SVF>>> = {}>(plugins: {
86
+ export declare function createPlugin<const XP extends Database.Plugin<{}, {}, {}, {}, never, {}, {}, {}, {}>, const IP extends Database.Plugin<{}, {}, {}, {}, never, {}, {}, {}, {}>, const CS extends ComponentSchemas, const RS extends ResourceSchemas, const A extends ArchetypeComponents<StringKeyof<RemoveIndex<CS> & XP['components'] & IP['components']>>, const IX extends IndexDeclarations<FromSchemas<RemoveIndex<CS> & XP['components'] & IP['components']>, RemoveIndex<A> & XP['archetypes'] & IP['archetypes']>, const TD extends TransactionDeclarations<FromSchemas<RemoveIndex<CS> & XP['components'] & IP['components']>, FromSchemas<RemoveIndex<RS> & XP['resources'] & IP['resources']>, RemoveIndex<A> & XP['archetypes'] & IP['archetypes'], RemoveIndex<IX> & XP['indexes'] & IP['indexes']>, const AD, const S extends string = never, const SVF extends ServiceFactories<Database.FromPlugin<AmbientPlugin<XP, IP>>> = {}, const CVF extends PluginComputedFactories<FullDBForPlugin<RemoveIndex<CS>, RemoveIndex<RS>, RemoveIndex<A>, RemoveIndex<TD>, S, RemoveIndex<AD> & XP['actions'] & IP['actions'], AmbientPlugin<XP, IP>, RemoveIndex<SVF>, RemoveIndex<IX>>> = {}>(plugins: {
87
87
  imports?: IP;
88
88
  extends?: XP;
89
89
  services?: SVF & {
@@ -93,7 +93,7 @@ export declare function createPlugin<const XP extends Database.Plugin<{}, {}, {}
93
93
  resources?: RS;
94
94
  archetypes?: A;
95
95
  indexes?: IX;
96
- computed?: CVF & PluginComputedFactories<FullDBForPlugin<RemoveIndex<CS>, RemoveIndex<RS>, RemoveIndex<A>, {}, string, RemoveIndex<AD> & XP['actions'] & IP['actions'], AmbientPlugin<XP, IP>, RemoveIndex<SVF>>>;
96
+ computed?: CVF & PluginComputedFactories<FullDBForPlugin<RemoveIndex<CS>, RemoveIndex<RS>, RemoveIndex<A>, {}, string, RemoveIndex<AD> & XP['actions'] & IP['actions'], AmbientPlugin<XP, IP>, RemoveIndex<SVF>, RemoveIndex<IX>>>;
97
97
  transactions?: TD;
98
98
  actions?: AD & {
99
99
  readonly [K: string]: (db: Database<FromSchemas<RemoveIndex<CS> & XP['components'] & IP['components']>, FromSchemas<RemoveIndex<RS> & XP['resources'] & IP['resources']>, RemoveIndex<A> & XP['archetypes'] & IP['archetypes'], ToTransactionFunctions<RemoveIndex<TD> & XP['transactions'] & IP['transactions']>, S | StringKeyof<XP['systems']> | StringKeyof<IP['systems']>, ToActionFunctions<XP['actions'] & IP['actions']>, FromServiceFactories<RemoveIndex<SVF> & XP['services'] & IP['services']>, FromComputedFactories<RemoveIndex<CVF> & XP['computed'] & IP['computed']>, RemoveIndex<IX> & XP['indexes'] & IP['indexes']>, input?: any) => any;
@@ -1 +1 @@
1
- {"version":3,"file":"create-plugin.js","sourceRoot":"","sources":["../../../src/ecs/database/create-plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create-plugin.js","sourceRoot":"","sources":["../../../src/ecs/database/create-plugin.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Archetype, ArchetypeId, ReadonlyArchetype } from "../archetype/index.js";
1
+ import { Archetype, ArchetypeId, FromArchetype, ReadonlyArchetype } from "../archetype/index.js";
2
2
  import { ResourceComponents } from "../store/resource-components.js";
3
3
  import { ReadonlyStore, Store } from "../store/index.js";
4
4
  import { Entity } from "../entity/entity.js";
@@ -216,6 +216,22 @@ export declare namespace Database {
216
216
  namespace Index {
217
217
  type Handle<C extends Components, I extends StoreIndex<C, any, any, any>> = StoreIndex.Handle<C, I>;
218
218
  }
219
+ namespace Archetype {
220
+ /**
221
+ * The row (component) type of the archetype named `K` on a store /
222
+ * database / service type `S`. Lets callers *name* an archetype row
223
+ * without re-spelling its columns — derive instead of re-declare.
224
+ *
225
+ * ```ts
226
+ * type MainService = Database.Plugin.ToDatabase<typeof mainPlugin>;
227
+ * type Track = Database.Archetype.RowOf<MainService, "Track">;
228
+ * const t: ReadonlyArchetype<Track> = db.archetypes.Track; // no cast
229
+ * ```
230
+ */
231
+ type RowOf<S extends {
232
+ readonly archetypes: Record<string, unknown>;
233
+ }, K extends StringKeyof<S["archetypes"]>> = FromArchetype<S["archetypes"][K]>;
234
+ }
219
235
  type Plugin<CS extends ComponentSchemas = any, RS extends ResourceSchemas = any, A extends ArchetypeComponents<StringKeyof<CS>> = any, TD extends TransactionDeclarations<FromSchemas<CS>, FromSchemas<RS>, any> = any, S extends string = any, AD extends ActionDeclarations<FromSchemas<CS>, FromSchemas<RS>, A, ToTransactionFunctions<TD>, S> = any, SVF extends ServiceFactories = any, CVF extends ComputedFactories = any, IX extends IndexDeclarations<FromSchemas<CS>> = any> = {
220
236
  readonly components: CS;
221
237
  readonly resources: RS;
@@ -1,6 +1,8 @@
1
1
  // © 2026 Adobe. MIT License. See /LICENSE for details.
2
2
  import { describe, it, expect } from "vitest";
3
3
  import { Database } from "./database.js";
4
+ import { Entity } from "../entity/entity.js";
5
+ import { FractionalIndex } from "../../schema/fractional-index/fractional-index.js";
4
6
  // ============================================================================
5
7
  // Catalogue pattern coverage — each describe corresponds to one of the 12
6
8
  // patterns in `packages/data/src/ecs/README.md`. The tests assert runtime
@@ -1264,4 +1266,69 @@ describe("registry maintenance", () => {
1264
1266
  expect([...ext.indexes.byName.find({ name: "alice" })].sort()).toEqual([e1, e2].sort());
1265
1267
  });
1266
1268
  });
1269
+ describe("complex sort index — orderedChildOf (nested parent + fractional-index order)", () => {
1270
+ // orderedChildOf bundles the parent entity reference and the fractional-index
1271
+ // sort key in a single object component. The index uses a computed slot map
1272
+ // to extract the group key and a custom compare that drills into the nested
1273
+ // object for the order field — matching the README pattern:
1274
+ // key: (f) => f.parent, order: { by: ["foo"], compare: (a, b) => a.foo.order < b.foo.order ? -1 : 1 }
1275
+ const plugin = () => Database.Plugin.create({
1276
+ components: {
1277
+ orderedChildOf: {
1278
+ type: "object",
1279
+ properties: {
1280
+ parent: Entity.schema,
1281
+ order: FractionalIndex.schema,
1282
+ },
1283
+ required: ["parent", "order"],
1284
+ },
1285
+ },
1286
+ archetypes: { Child: ["orderedChildOf"] },
1287
+ indexes: {
1288
+ orderedChildrenOf: {
1289
+ key: { parent: (c) => c.orderedChildOf.parent },
1290
+ components: ["orderedChildOf"],
1291
+ order: {
1292
+ by: ["orderedChildOf"],
1293
+ compare: (a, b) => a.orderedChildOf.order < b.orderedChildOf.order ? -1 : 1,
1294
+ },
1295
+ },
1296
+ },
1297
+ transactions: {
1298
+ add: (t, args) => t.archetypes.Child.insert({ orderedChildOf: args }),
1299
+ reorder: (t, args) => t.update(args.entity, { orderedChildOf: { parent: args.parent, order: args.order } }),
1300
+ delete: (t, e) => t.delete(e),
1301
+ },
1302
+ });
1303
+ it("returns children sorted by fractional index within the same parent", () => {
1304
+ const db = Database.create(plugin());
1305
+ const c = db.transactions.add({ parent: 1, order: "a2" });
1306
+ const a = db.transactions.add({ parent: 1, order: "a0" });
1307
+ const b = db.transactions.add({ parent: 1, order: "a1" });
1308
+ expect(db.indexes.orderedChildrenOf.find({ parent: 1 })).toEqual([a, b, c]);
1309
+ });
1310
+ it("children of different parents are in independent buckets", () => {
1311
+ const db = Database.create(plugin());
1312
+ const child1 = db.transactions.add({ parent: 1, order: "a0" });
1313
+ const child2 = db.transactions.add({ parent: 2, order: "a0" });
1314
+ expect(db.indexes.orderedChildrenOf.find({ parent: 1 })).toEqual([child1]);
1315
+ expect(db.indexes.orderedChildrenOf.find({ parent: 2 })).toEqual([child2]);
1316
+ });
1317
+ it("reordering an entity repositions it in the sorted result", () => {
1318
+ const db = Database.create(plugin());
1319
+ const a = db.transactions.add({ parent: 1, order: "a0" });
1320
+ const b = db.transactions.add({ parent: 1, order: "a1" });
1321
+ const c = db.transactions.add({ parent: 1, order: "a2" });
1322
+ db.transactions.reorder({ entity: a, parent: 1, order: "a3" });
1323
+ expect(db.indexes.orderedChildrenOf.find({ parent: 1 })).toEqual([b, c, a]);
1324
+ });
1325
+ it("delete removes the entity from its sorted bucket", () => {
1326
+ const db = Database.create(plugin());
1327
+ const a = db.transactions.add({ parent: 1, order: "a0" });
1328
+ const b = db.transactions.add({ parent: 1, order: "a1" });
1329
+ const c = db.transactions.add({ parent: 1, order: "a2" });
1330
+ db.transactions.delete(b);
1331
+ expect(db.indexes.orderedChildrenOf.find({ parent: 1 })).toEqual([a, c]);
1332
+ });
1333
+ });
1267
1334
  //# sourceMappingURL=database.index.test.js.map