@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.
- package/dist/ecs/database/archetype-row.type-test.d.ts +1 -0
- package/dist/ecs/database/archetype-row.type-test.js +31 -0
- package/dist/ecs/database/archetype-row.type-test.js.map +1 -0
- package/dist/ecs/database/combine-plugins.d.ts +8 -7
- package/dist/ecs/database/combine-plugins.js.map +1 -1
- package/dist/ecs/database/combine-plugins.type-test.d.ts +1 -0
- package/dist/ecs/database/combine-plugins.type-test.js +37 -0
- package/dist/ecs/database/combine-plugins.type-test.js.map +1 -0
- package/dist/ecs/database/create-plugin.d.ts +3 -3
- package/dist/ecs/database/create-plugin.js.map +1 -1
- package/dist/ecs/database/database.d.ts +17 -1
- package/dist/ecs/database/database.index.test.js +67 -0
- package/dist/ecs/database/database.index.test.js.map +1 -1
- package/dist/ecs/database/database.index.type-test.js +45 -0
- package/dist/ecs/database/database.index.type-test.js.map +1 -1
- package/dist/ecs/database/database.js.map +1 -1
- package/dist/ecs/database/deep-extends-chain.type-test.d.ts +77 -60
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/references/data-lit/package.json +1 -1
- package/references/data-lit-tictactoe/package.json +1 -1
- package/references/data-react/package.json +1 -1
- package/references/data-react-hello/package.json +1 -1
- package/references/data-react-pixie/package.json +1 -1
|
@@ -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 {
|
|
1
|
+
import { StringKeyof, UnionToIntersection } from "../../types/types.js";
|
|
2
2
|
import type { Database } from "./database.js";
|
|
3
|
-
type IntersectAll<T extends readonly unknown[]> =
|
|
4
|
-
|
|
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<
|
|
14
|
+
}>, Extract<{
|
|
14
15
|
[K in keyof Plugins]: StringKeyof<Plugins[K]['systems']>;
|
|
15
|
-
}
|
|
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<
|
|
41
|
+
}>, Extract<{
|
|
41
42
|
[K in keyof Plugins]: StringKeyof<Plugins[K]['systems']>;
|
|
42
|
-
}
|
|
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;
|
|
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
|
|
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":"AAAA,uDAAuD;AAUvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AA0CtD,SAAS,qBAAqB,CAAC,OAAgC;IAC3D,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAC/J,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,OAAO,CAAC,CAAC;IAE7D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,aAAa,GAAG,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjD,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,6CAA6C,GAAG,4BAA4B,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5H,CAAC;QACD,uDAAuD;QACvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YAC/B,MAAM,iBAAiB,GAAG,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACzD,IAAI,iBAAiB,GAAG,aAAa,EAAE,CAAC;gBACpC,MAAM,IAAI,KAAK,CACX,qCAAqC,GAAG,uBAAuB,OAAO,KAAK;oBAC3E,mBAAmB,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACrF,CAAC;YACN,CAAC;QACL,CAAC;IACL,CAAC;AACL,CAAC;
|
|
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
|