Skip to content

feat(data): Set/Map data model, type-driven conformance ordering, Services injection - #168

Merged
krisnye merged 4 commits into
mainfrom
krisnye/set-map-data-model
Aug 12, 2026
Merged

feat(data): Set/Map data model, type-driven conformance ordering, Services injection#168
krisnye merged 4 commits into
mainfrom
krisnye/set-map-data-model

Conversation

@krisnye

@krisnye krisnye commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Description

Makes Set/Map first-class in the data model, pushes ordered-vs-unordered semantics into the type system, formalizes how services are injected into transitions, and names the two feature-authoring modes.

Data.stringify / Data.parse

A lower-level JSON serializer extended to round-trip Map and Set in both directions (plain JSON.stringify renders them as {}), surfaced on the Data namespace. The store's serialize/deserialize now route through it, so Set/Map values persist.

Set/Map as first-class Data

Data, IsData, DeepReadonly, and equals all handle ReadonlySet/ReadonlyMap. equals compares them order-independently (elements/values recurse). mutableClone already worked via structuredClone. Verified end-to-end that a stored typed-buffer column of Maps/Sets round-trips.

Type-driven conformance ordering

The comparator now derives ordering from the value's type — ReadonlyArray positional, ReadonlySet/ReadonlyMap order-independent — so the match.unordered option is removed. A numeric id is auto-ignored unless a case pins it, and Match.ref correspondence now holds across a Set boundary (backtracking pairing). Space-rock, hopper, and pixie model their unordered entity bags as ReadonlySet.

Formalized service injection

Each feature's services/ root exports one Services map; transitions inject with Pick<Services, ...> instead of ad-hoc inline types. Each service-database carries a compile-time drift-guard pinning db.services to Services. Migrated data-lit-todo and data-lit-space-rock-game.

Two feature modes: state-based vs. ECS-based

Names the two authoring modes, discriminated by the presence of data/state/. State-based (the mode for all new features): a Functional State Specification is the source of truth and the ECS is conformance-verified against it. ECS-based (legacy — features predating the state-based approach): the ECS is the source of truth, no data/state/, no conformance, so every transaction and action carries its own unit test. Documented in the data-ai rules (features/index.md plus gates in conformance.md / transactions.md / actions.md / data/state.md).

Docs

Updated @adobe/data README/AGENTS and the data-ai rules (data-modelling.md, data/state.md, data/index.md, services/index.md, conformance.md, service.md, features/index.md, transactions.md, actions.md).

Testing

  • Full recursive lint and typecheck clean across all 18 packages
  • @adobe/data 3011 tests, data-testing 12, data-lit-todo 102, data-lit-space-rock-game 135, data-gpu-hopper 90, data-react-pixie 42 — all passing (Node 24)

🤖 Generated with Claude Code

…ordering

- Add Data.stringify/parse (JSON extended with Map/Set) and route store serialize/deserialize through it
- Data / IsData / DeepReadonly / equals now handle ReadonlySet & ReadonlyMap
- Conformance compares by type: ReadonlyArray ordered, Set/Map order-independent; remove match.unordered, auto-ignore entity id, support ref correspondence across Set boundaries
- Migrate space-rock, hopper, pixie unordered entity bags to ReadonlySet
- Formalize service injection: per-feature services/services.ts Services map + Pick<Services,...> in transitions + service-database drift-guard (todo, space-rock)
- Update @adobe/data README/AGENTS and data-ai rules/docs; bump to 0.9.97

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@krisnye
krisnye force-pushed the krisnye/set-map-data-model branch from d7e71d0 to 5b379f8 Compare August 12, 2026 07:37
Discriminate mode by presence of data/state: state-based (a Functional State
Specification is the source of truth, ECS conformance-verified against it) vs
ECS-based (ECS is the source of truth, no data/state, no conformance). In
ECS-based mode every transaction and action carries its own unit test, since
there are no conformance cases. Adds the Two-modes section to features/index.md
and gates conformance.md / transactions.md / actions.md / data/state.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@krisnye
krisnye force-pushed the krisnye/set-map-data-model branch from 5b379f8 to 01738a3 Compare August 12, 2026 07:39
the semantics: `ReadonlyArray` compares positionally, `ReadonlySet` / `ReadonlyMap`
order-independently, and a numeric `id` is ignored (the ECS allocates it) — so there
is no separate "unordered" declaration when writing conformance cases.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic seems duplicated elsewhere. Let's leave it here and just reference it from the other rules instead of duplicating it.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 34ae293 — kept the ordering-by-type rule canonical here in data-modelling.md; data/state.md and conformance.md now reference it instead of restating it.

krisnye and others added 2 commits August 12, 2026 00:51
…modelling.md

Keep the ordering-by-type explanation canonical in data-modelling.md; state.md
and conformance.md now reference it instead of restating it (per PR review).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ap> doesn't strip .set

The Set/Map DeepReadonly change turns a resource's Map value into ReadonlyMap;
this runtime nonPersistent URL->Entity cache is genuinely mutable, so flag it
mutable:true (same as rigid-stack). Missed locally due to a stale tsc -b
incremental cache; a clean build reproduces the CI failure.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@krisnye
krisnye merged commit 1c41813 into main Aug 12, 2026
3 checks passed
@krisnye
krisnye deleted the krisnye/set-map-data-model branch August 12, 2026 08:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant