@forgeax/engine-ecs 0.1.2
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/LICENSE +202 -0
- package/README.md +272 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/__fixtures__/field-shape-fixture.d.ts +16 -0
- package/dist/__fixtures__/field-shape-fixture.d.ts.map +1 -0
- package/dist/__tests__/__fixtures__/inspect-scripts.snapshot.d.ts +3 -0
- package/dist/__tests__/__fixtures__/inspect-scripts.snapshot.d.ts.map +1 -0
- package/dist/__tests__/archetype.unit.test.d.ts +2 -0
- package/dist/__tests__/archetype.unit.test.d.ts.map +1 -0
- package/dist/__tests__/array-handle-element.test-d.d.ts +2 -0
- package/dist/__tests__/array-handle-element.test-d.d.ts.map +1 -0
- package/dist/__tests__/buffer-array-vocab.test-d.d.ts +2 -0
- package/dist/__tests__/buffer-array-vocab.test-d.d.ts.map +1 -0
- package/dist/__tests__/buffer-field-input-widen.unit.test.d.ts +2 -0
- package/dist/__tests__/buffer-field-input-widen.unit.test.d.ts.map +1 -0
- package/dist/__tests__/buffer-pool.test-d.d.ts +2 -0
- package/dist/__tests__/buffer-pool.test-d.d.ts.map +1 -0
- package/dist/__tests__/change-detection.unit.test.d.ts +2 -0
- package/dist/__tests__/change-detection.unit.test.d.ts.map +1 -0
- package/dist/__tests__/command-buffer.test.d.ts +2 -0
- package/dist/__tests__/command-buffer.test.d.ts.map +1 -0
- package/dist/__tests__/commands-deferred.unit.test.d.ts +2 -0
- package/dist/__tests__/commands-deferred.unit.test.d.ts.map +1 -0
- package/dist/__tests__/component-catalog.test.d.ts +2 -0
- package/dist/__tests__/component-catalog.test.d.ts.map +1 -0
- package/dist/__tests__/component-definition-identity.unit.test.d.ts +2 -0
- package/dist/__tests__/component-definition-identity.unit.test.d.ts.map +1 -0
- package/dist/__tests__/component-schema.test-d.d.ts +2 -0
- package/dist/__tests__/component-schema.test-d.d.ts.map +1 -0
- package/dist/__tests__/component-schema.test.d.ts +2 -0
- package/dist/__tests__/component-schema.test.d.ts.map +1 -0
- package/dist/__tests__/define-component-options.test-d.d.ts +2 -0
- package/dist/__tests__/define-component-options.test-d.d.ts.map +1 -0
- package/dist/__tests__/deprecated-vocab-rejection.unit.test.d.ts +2 -0
- package/dist/__tests__/deprecated-vocab-rejection.unit.test.d.ts.map +1 -0
- package/dist/__tests__/despawn-all.unit.test.d.ts +2 -0
- package/dist/__tests__/despawn-all.unit.test.d.ts.map +1 -0
- package/dist/__tests__/ecs-core-reduction.characterization.test.d.ts +2 -0
- package/dist/__tests__/ecs-core-reduction.characterization.test.d.ts.map +1 -0
- package/dist/__tests__/ecs-core-reduction.perf.test.d.ts +2 -0
- package/dist/__tests__/ecs-core-reduction.perf.test.d.ts.map +1 -0
- package/dist/__tests__/ecs-error-code-31.test-d.d.ts +2 -0
- package/dist/__tests__/ecs-error-code-31.test-d.d.ts.map +1 -0
- package/dist/__tests__/entity-disabling.unit.test.d.ts +2 -0
- package/dist/__tests__/entity-disabling.unit.test.d.ts.map +1 -0
- package/dist/__tests__/entity-handle-codec-parity.unit.test.d.ts +2 -0
- package/dist/__tests__/entity-handle-codec-parity.unit.test.d.ts.map +1 -0
- package/dist/__tests__/errors.unit.test.d.ts +2 -0
- package/dist/__tests__/errors.unit.test.d.ts.map +1 -0
- package/dist/__tests__/execution-conflict-boundary.unit.test.d.ts +2 -0
- package/dist/__tests__/execution-conflict-boundary.unit.test.d.ts.map +1 -0
- package/dist/__tests__/execution-shared-storage.unit.test.d.ts +2 -0
- package/dist/__tests__/execution-shared-storage.unit.test.d.ts.map +1 -0
- package/dist/__tests__/externalization-portable-value.unit.test.d.ts +2 -0
- package/dist/__tests__/externalization-portable-value.unit.test.d.ts.map +1 -0
- package/dist/__tests__/externalization-projection.unit.test.d.ts +2 -0
- package/dist/__tests__/externalization-projection.unit.test.d.ts.map +1 -0
- package/dist/__tests__/externalization-root-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/externalization-root-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/field-enum-labels-reflection.test.d.ts +2 -0
- package/dist/__tests__/field-enum-labels-reflection.test.d.ts.map +1 -0
- package/dist/__tests__/field-shape-fixture.test.d.ts +2 -0
- package/dist/__tests__/field-shape-fixture.test.d.ts.map +1 -0
- package/dist/__tests__/field-transient-reflection.test.d.ts +2 -0
- package/dist/__tests__/field-transient-reflection.test.d.ts.map +1 -0
- package/dist/__tests__/field-value-type.test-d.d.ts +2 -0
- package/dist/__tests__/field-value-type.test-d.d.ts.map +1 -0
- package/dist/__tests__/fixed-update.unit.test.d.ts +2 -0
- package/dist/__tests__/fixed-update.unit.test.d.ts.map +1 -0
- package/dist/__tests__/handle.test-d.d.ts +2 -0
- package/dist/__tests__/handle.test-d.d.ts.map +1 -0
- package/dist/__tests__/hierarchy.unit.test.d.ts +2 -0
- package/dist/__tests__/hierarchy.unit.test.d.ts.map +1 -0
- package/dist/__tests__/managed-array-vocab.test-d.d.ts +2 -0
- package/dist/__tests__/managed-array-vocab.test-d.d.ts.map +1 -0
- package/dist/__tests__/minimal-example.test-d.d.ts +2 -0
- package/dist/__tests__/minimal-example.test-d.d.ts.map +1 -0
- package/dist/__tests__/name-read-types.test-d.d.ts +2 -0
- package/dist/__tests__/name-read-types.test-d.d.ts.map +1 -0
- package/dist/__tests__/plugin-service.test.d.ts +2 -0
- package/dist/__tests__/plugin-service.test.d.ts.map +1 -0
- package/dist/__tests__/query-combinations.unit.test.d.ts +2 -0
- package/dist/__tests__/query-combinations.unit.test.d.ts.map +1 -0
- package/dist/__tests__/query-light-extract-flat-column-ratio.perf.test.d.ts +2 -0
- package/dist/__tests__/query-light-extract-flat-column-ratio.perf.test.d.ts.map +1 -0
- package/dist/__tests__/query-storage-trends.perf.test.d.ts +2 -0
- package/dist/__tests__/query-storage-trends.perf.test.d.ts.map +1 -0
- package/dist/__tests__/query-trs-flat-column-ratio.perf.test.d.ts +2 -0
- package/dist/__tests__/query-trs-flat-column-ratio.perf.test.d.ts.map +1 -0
- package/dist/__tests__/query.unit.test.d.ts +2 -0
- package/dist/__tests__/query.unit.test.d.ts.map +1 -0
- package/dist/__tests__/relationship-index.perf.test.d.ts +2 -0
- package/dist/__tests__/relationship-index.perf.test.d.ts.map +1 -0
- package/dist/__tests__/relationship-index.test.d.ts +2 -0
- package/dist/__tests__/relationship-index.test.d.ts.map +1 -0
- package/dist/__tests__/scalar-field-type-owner.test-d.d.ts +2 -0
- package/dist/__tests__/scalar-field-type-owner.test-d.d.ts.map +1 -0
- package/dist/__tests__/schedule-determinism.unit.test.d.ts +2 -0
- package/dist/__tests__/schedule-determinism.unit.test.d.ts.map +1 -0
- package/dist/__tests__/schedule-inspection.unit.test.d.ts +2 -0
- package/dist/__tests__/schedule-inspection.unit.test.d.ts.map +1 -0
- package/dist/__tests__/schedule-scope-error.unit.test.d.ts +2 -0
- package/dist/__tests__/schedule-scope-error.unit.test.d.ts.map +1 -0
- package/dist/__tests__/schedule-token.unit.test.d.ts +2 -0
- package/dist/__tests__/schedule-token.unit.test.d.ts.map +1 -0
- package/dist/__tests__/schema-vocab.test-d.d.ts +2 -0
- package/dist/__tests__/schema-vocab.test-d.d.ts.map +1 -0
- package/dist/__tests__/serialization.unit.test.d.ts +2 -0
- package/dist/__tests__/serialization.unit.test.d.ts.map +1 -0
- package/dist/__tests__/shared-kernel-eligibility.test-d.d.ts +2 -0
- package/dist/__tests__/shared-kernel-eligibility.test-d.d.ts.map +1 -0
- package/dist/__tests__/shared-kernel-eligibility.unit.test.d.ts +2 -0
- package/dist/__tests__/shared-kernel-eligibility.unit.test.d.ts.map +1 -0
- package/dist/__tests__/shared-ref-store.unit.test.d.ts +2 -0
- package/dist/__tests__/shared-ref-store.unit.test.d.ts.map +1 -0
- package/dist/__tests__/sparse-tag.unit.test.d.ts +2 -0
- package/dist/__tests__/sparse-tag.unit.test.d.ts.map +1 -0
- package/dist/__tests__/spawn-field-error.test-d.d.ts +2 -0
- package/dist/__tests__/spawn-field-error.test-d.d.ts.map +1 -0
- package/dist/__tests__/stale-error.test-d.d.ts +2 -0
- package/dist/__tests__/stale-error.test-d.d.ts.map +1 -0
- package/dist/__tests__/string-view-symmetry.test-d.d.ts +2 -0
- package/dist/__tests__/string-view-symmetry.test-d.d.ts.map +1 -0
- package/dist/__tests__/string-vocab.test-d.d.ts +2 -0
- package/dist/__tests__/string-vocab.test-d.d.ts.map +1 -0
- package/dist/__tests__/structure-epoch-boundaries.unit.test.d.ts +2 -0
- package/dist/__tests__/structure-epoch-boundaries.unit.test.d.ts.map +1 -0
- package/dist/__tests__/structure-epoch.unit.test.d.ts +2 -0
- package/dist/__tests__/structure-epoch.unit.test.d.ts.map +1 -0
- package/dist/__tests__/table-archetype-mapping.unit.test.d.ts +2 -0
- package/dist/__tests__/table-archetype-mapping.unit.test.d.ts.map +1 -0
- package/dist/__tests__/time.unit.test.d.ts +2 -0
- package/dist/__tests__/time.unit.test.d.ts.map +1 -0
- package/dist/__tests__/types.test-d.d.ts +2 -0
- package/dist/__tests__/types.test-d.d.ts.map +1 -0
- package/dist/__tests__/unique-ref-store.unit.test.d.ts +2 -0
- package/dist/__tests__/unique-ref-store.unit.test.d.ts.map +1 -0
- package/dist/__tests__/utils/handle-numeric.d.ts +14 -0
- package/dist/__tests__/utils/handle-numeric.d.ts.map +1 -0
- package/dist/__tests__/validation-root-surface.unit.test.d.ts +2 -0
- package/dist/__tests__/validation-root-surface.unit.test.d.ts.map +1 -0
- package/dist/__tests__/visibility-atomic-write.unit.test.d.ts +2 -0
- package/dist/__tests__/visibility-atomic-write.unit.test.d.ts.map +1 -0
- package/dist/__tests__/world-change-journal.unit.test.d.ts +2 -0
- package/dist/__tests__/world-change-journal.unit.test.d.ts.map +1 -0
- package/dist/__tests__/world-characterization.unit.test.d.ts +2 -0
- package/dist/__tests__/world-characterization.unit.test.d.ts.map +1 -0
- package/dist/__tests__/world-consumer-inference.test-d.d.ts +2 -0
- package/dist/__tests__/world-consumer-inference.test-d.d.ts.map +1 -0
- package/dist/__tests__/world-health.contract.test.d.ts +2 -0
- package/dist/__tests__/world-health.contract.test.d.ts.map +1 -0
- package/dist/__tests__/world-inspection.test.d.ts +2 -0
- package/dist/__tests__/world-inspection.test.d.ts.map +1 -0
- package/dist/__tests__/world-internal-identity.unit.test.d.ts +2 -0
- package/dist/__tests__/world-internal-identity.unit.test.d.ts.map +1 -0
- package/dist/__tests__/world-managed-roundtrip.unit.test.d.ts +2 -0
- package/dist/__tests__/world-managed-roundtrip.unit.test.d.ts.map +1 -0
- package/dist/__tests__/world-scheduling.m4.test.d.ts +2 -0
- package/dist/__tests__/world-scheduling.m4.test.d.ts.map +1 -0
- package/dist/__tests__/world-unique-roundtrip.unit.test.d.ts +2 -0
- package/dist/__tests__/world-unique-roundtrip.unit.test.d.ts.map +1 -0
- package/dist/__tests__/world.test-d.d.ts +2 -0
- package/dist/__tests__/world.test-d.d.ts.map +1 -0
- package/dist/buffer-pool.d.ts +109 -0
- package/dist/buffer-pool.d.ts.map +1 -0
- package/dist/commands.d.ts +93 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/component-default-fallback.d.ts +88 -0
- package/dist/component-default-fallback.d.ts.map +1 -0
- package/dist/component-schema.d.ts +34 -0
- package/dist/component-schema.d.ts.map +1 -0
- package/dist/component-value-validate.d.ts +29 -0
- package/dist/component-value-validate.d.ts.map +1 -0
- package/dist/component.d.ts +581 -0
- package/dist/component.d.ts.map +1 -0
- package/dist/entity-handle.d.ts +68 -0
- package/dist/entity-handle.d.ts.map +1 -0
- package/dist/entity.d.ts +86 -0
- package/dist/entity.d.ts.map +1 -0
- package/dist/errors/query-and-component-errors.d.ts +132 -0
- package/dist/errors/query-and-component-errors.d.ts.map +1 -0
- package/dist/errors/relationship-errors.d.ts +112 -0
- package/dist/errors/relationship-errors.d.ts.map +1 -0
- package/dist/errors/sprite-and-shared-errors.d.ts +107 -0
- package/dist/errors/sprite-and-shared-errors.d.ts.map +1 -0
- package/dist/errors/validation-errors.d.ts +214 -0
- package/dist/errors/validation-errors.d.ts.map +1 -0
- package/dist/errors.d.ts +756 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/execution/shared-kernel.d.ts +106 -0
- package/dist/execution/shared-kernel.d.ts.map +1 -0
- package/dist/externalization/index.d.ts +31 -0
- package/dist/externalization/index.d.ts.map +1 -0
- package/dist/externalization/index.mjs +298 -0
- package/dist/externalization/index.mjs.map +1 -0
- package/dist/index.d.ts +261 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +7354 -0
- package/dist/index.mjs.map +1 -0
- package/dist/internal.mjs +479 -0
- package/dist/internal.mjs.map +1 -0
- package/dist/plugin-service.d.ts +11 -0
- package/dist/plugin-service.d.ts.map +1 -0
- package/dist/projection/index.d.ts +50 -0
- package/dist/projection/index.d.ts.map +1 -0
- package/dist/projection/index.mjs +517 -0
- package/dist/projection/index.mjs.map +1 -0
- package/dist/query/query.d.ts +58 -0
- package/dist/query/query.d.ts.map +1 -0
- package/dist/relationship-index.d.ts +81 -0
- package/dist/relationship-index.d.ts.map +1 -0
- package/dist/resource.d.ts +70 -0
- package/dist/resource.d.ts.map +1 -0
- package/dist/schedule-token.d.ts +16 -0
- package/dist/schedule-token.d.ts.map +1 -0
- package/dist/schedule.d.ts +271 -0
- package/dist/schedule.d.ts.map +1 -0
- package/dist/shared-ref-store.d.ts +144 -0
- package/dist/shared-ref-store.d.ts.map +1 -0
- package/dist/shared.d.ts +3 -0
- package/dist/shared.d.ts.map +1 -0
- package/dist/shared.mjs +364 -0
- package/dist/shared.mjs.map +1 -0
- package/dist/storage/archetype-graph.d.ts +54 -0
- package/dist/storage/archetype-graph.d.ts.map +1 -0
- package/dist/storage/archetype.d.ts +23 -0
- package/dist/storage/archetype.d.ts.map +1 -0
- package/dist/storage/change-detection.d.ts +40 -0
- package/dist/storage/change-detection.d.ts.map +1 -0
- package/dist/storage/column.d.ts +111 -0
- package/dist/storage/column.d.ts.map +1 -0
- package/dist/storage/table.d.ts +29 -0
- package/dist/storage/table.d.ts.map +1 -0
- package/dist/time.d.ts +57 -0
- package/dist/time.d.ts.map +1 -0
- package/dist/unique-ref-store.d.ts +105 -0
- package/dist/unique-ref-store.d.ts.map +1 -0
- package/dist/world-change-journal.d.ts +34 -0
- package/dist/world-change-journal.d.ts.map +1 -0
- package/dist/world-component-access.d.ts +264 -0
- package/dist/world-component-access.d.ts.map +1 -0
- package/dist/world-component-storage.d.ts +282 -0
- package/dist/world-component-storage.d.ts.map +1 -0
- package/dist/world-core.d.ts +39 -0
- package/dist/world-core.d.ts.map +1 -0
- package/dist/world-entity-lifecycle.d.ts +30 -0
- package/dist/world-entity-lifecycle.d.ts.map +1 -0
- package/dist/world-internal.d.ts +14 -0
- package/dist/world-internal.d.ts.map +1 -0
- package/dist/world-scheduling.d.ts +30 -0
- package/dist/world-scheduling.d.ts.map +1 -0
- package/dist/world.d.ts +620 -0
- package/dist/world.d.ts.map +1 -0
- package/package.json +77 -0
- package/src/__fixtures__/field-shape-fixture.ts +30 -0
- package/src/__tests__/__fixtures__/inspect-scripts.snapshot.ts +2 -0
- package/src/__tests__/archetype.unit.test.ts +1837 -0
- package/src/__tests__/array-handle-element.test-d.ts +34 -0
- package/src/__tests__/buffer-array-vocab.test-d.ts +53 -0
- package/src/__tests__/buffer-field-input-widen.unit.test.ts +99 -0
- package/src/__tests__/buffer-pool.test-d.ts +32 -0
- package/src/__tests__/change-detection.unit.test.ts +86 -0
- package/src/__tests__/command-buffer.test.ts +179 -0
- package/src/__tests__/commands-deferred.unit.test.ts +68 -0
- package/src/__tests__/component-catalog.test.ts +59 -0
- package/src/__tests__/component-definition-identity.unit.test.ts +24 -0
- package/src/__tests__/component-schema.test-d.ts +119 -0
- package/src/__tests__/component-schema.test.ts +55 -0
- package/src/__tests__/define-component-options.test-d.ts +35 -0
- package/src/__tests__/deprecated-vocab-rejection.unit.test.ts +59 -0
- package/src/__tests__/despawn-all.unit.test.ts +17 -0
- package/src/__tests__/ecs-core-reduction.characterization.test.ts +130 -0
- package/src/__tests__/ecs-core-reduction.perf.test.ts +260 -0
- package/src/__tests__/ecs-error-code-31.test-d.ts +42 -0
- package/src/__tests__/entity-disabling.unit.test.ts +37 -0
- package/src/__tests__/entity-handle-codec-parity.unit.test.ts +126 -0
- package/src/__tests__/errors.unit.test.ts +1452 -0
- package/src/__tests__/execution-conflict-boundary.unit.test.ts +123 -0
- package/src/__tests__/execution-shared-storage.unit.test.ts +40 -0
- package/src/__tests__/externalization-portable-value.unit.test.ts +275 -0
- package/src/__tests__/externalization-projection.unit.test.ts +325 -0
- package/src/__tests__/externalization-root-surface.unit.test.ts +33 -0
- package/src/__tests__/field-enum-labels-reflection.test.ts +66 -0
- package/src/__tests__/field-shape-fixture.test.ts +61 -0
- package/src/__tests__/field-transient-reflection.test.ts +59 -0
- package/src/__tests__/field-value-type.test-d.ts +57 -0
- package/src/__tests__/fixed-update.unit.test.ts +78 -0
- package/src/__tests__/handle.test-d.ts +86 -0
- package/src/__tests__/hierarchy.unit.test.ts +2534 -0
- package/src/__tests__/managed-array-vocab.test-d.ts +137 -0
- package/src/__tests__/minimal-example.test-d.ts +42 -0
- package/src/__tests__/name-read-types.test-d.ts +72 -0
- package/src/__tests__/plugin-service.test.ts +13 -0
- package/src/__tests__/query-combinations.unit.test.ts +42 -0
- package/src/__tests__/query-light-extract-flat-column-ratio.perf.test.ts +252 -0
- package/src/__tests__/query-storage-trends.perf.test.ts +104 -0
- package/src/__tests__/query-trs-flat-column-ratio.perf.test.ts +194 -0
- package/src/__tests__/query.unit.test.ts +196 -0
- package/src/__tests__/relationship-index.perf.test.ts +126 -0
- package/src/__tests__/relationship-index.test.ts +70 -0
- package/src/__tests__/scalar-field-type-owner.test-d.ts +71 -0
- package/src/__tests__/schedule-determinism.unit.test.ts +36 -0
- package/src/__tests__/schedule-inspection.unit.test.ts +81 -0
- package/src/__tests__/schedule-scope-error.unit.test.ts +63 -0
- package/src/__tests__/schedule-token.unit.test.ts +54 -0
- package/src/__tests__/schema-vocab.test-d.ts +103 -0
- package/src/__tests__/serialization.unit.test.ts +2740 -0
- package/src/__tests__/shared-kernel-eligibility.test-d.ts +18 -0
- package/src/__tests__/shared-kernel-eligibility.unit.test.ts +78 -0
- package/src/__tests__/shared-ref-store.unit.test.ts +646 -0
- package/src/__tests__/sparse-tag.unit.test.ts +201 -0
- package/src/__tests__/spawn-field-error.test-d.ts +41 -0
- package/src/__tests__/stale-error.test-d.ts +207 -0
- package/src/__tests__/string-view-symmetry.test-d.ts +26 -0
- package/src/__tests__/string-vocab.test-d.ts +49 -0
- package/src/__tests__/structure-epoch-boundaries.unit.test.ts +39 -0
- package/src/__tests__/structure-epoch.unit.test.ts +48 -0
- package/src/__tests__/table-archetype-mapping.unit.test.ts +78 -0
- package/src/__tests__/time.unit.test.ts +79 -0
- package/src/__tests__/types.test-d.ts +38 -0
- package/src/__tests__/unique-ref-store.unit.test.ts +348 -0
- package/src/__tests__/utils/handle-numeric.ts +30 -0
- package/src/__tests__/validation-root-surface.unit.test.ts +15 -0
- package/src/__tests__/visibility-atomic-write.unit.test.ts +82 -0
- package/src/__tests__/world-change-journal.unit.test.ts +97 -0
- package/src/__tests__/world-characterization.unit.test.ts +408 -0
- package/src/__tests__/world-consumer-inference.test-d.ts +16 -0
- package/src/__tests__/world-health.contract.test.ts +87 -0
- package/src/__tests__/world-inspection.test.ts +37 -0
- package/src/__tests__/world-internal-identity.unit.test.ts +17 -0
- package/src/__tests__/world-managed-roundtrip.unit.test.ts +98 -0
- package/src/__tests__/world-scheduling.m4.test.ts +52 -0
- package/src/__tests__/world-unique-roundtrip.unit.test.ts +357 -0
- package/src/__tests__/world.test-d.ts +156 -0
- package/src/buffer-pool.ts +357 -0
- package/src/commands.ts +644 -0
- package/src/component-default-fallback.ts +236 -0
- package/src/component-schema.ts +92 -0
- package/src/component-value-validate.ts +135 -0
- package/src/component.ts +1268 -0
- package/src/entity-handle.ts +104 -0
- package/src/entity.ts +140 -0
- package/src/errors/query-and-component-errors.ts +200 -0
- package/src/errors/relationship-errors.ts +198 -0
- package/src/errors/sprite-and-shared-errors.ts +231 -0
- package/src/errors/validation-errors.ts +418 -0
- package/src/errors.ts +1453 -0
- package/src/execution/shared-kernel.ts +392 -0
- package/src/externalization/index.ts +170 -0
- package/src/index.ts +414 -0
- package/src/plugin-service.ts +35 -0
- package/src/projection/index.ts +142 -0
- package/src/query/query.ts +606 -0
- package/src/relationship-index.ts +175 -0
- package/src/resource.ts +106 -0
- package/src/schedule-token.ts +40 -0
- package/src/schedule.ts +846 -0
- package/src/shared-ref-store.ts +418 -0
- package/src/shared.ts +23 -0
- package/src/storage/archetype-graph.ts +166 -0
- package/src/storage/archetype.ts +78 -0
- package/src/storage/change-detection.ts +231 -0
- package/src/storage/column.ts +247 -0
- package/src/storage/table.ts +153 -0
- package/src/time.ts +122 -0
- package/src/unique-ref-store.ts +278 -0
- package/src/world-change-journal.ts +84 -0
- package/src/world-component-access.ts +1412 -0
- package/src/world-component-storage.ts +1178 -0
- package/src/world-core.ts +74 -0
- package/src/world-entity-lifecycle.ts +539 -0
- package/src/world-internal.ts +75 -0
- package/src/world-scheduling.ts +499 -0
- package/src/world.ts +1397 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { type Component, type ComponentSchema } from './component';
|
|
2
|
+
import type { EntityHandle } from './entity-handle';
|
|
3
|
+
declare const relationshipTargetBrand: unique symbol;
|
|
4
|
+
/** A relationship target is a read projection, never a structural-write token. */
|
|
5
|
+
export type RelationshipTargetComponent<C extends Component = Component> = C & {
|
|
6
|
+
readonly [relationshipTargetBrand]: true;
|
|
7
|
+
};
|
|
8
|
+
/** The two immutable roles produced by one relationship declaration. */
|
|
9
|
+
export interface RelationshipDefinition {
|
|
10
|
+
readonly source: Component<string, ComponentSchema>;
|
|
11
|
+
readonly target: RelationshipTargetComponent<Component<string, ComponentSchema>>;
|
|
12
|
+
}
|
|
13
|
+
export interface RelationshipOptions {
|
|
14
|
+
readonly sourceName: string;
|
|
15
|
+
readonly sourceField: string;
|
|
16
|
+
readonly targetName: string;
|
|
17
|
+
readonly targetField: string;
|
|
18
|
+
readonly exclusive?: boolean;
|
|
19
|
+
readonly linkedSpawn?: boolean;
|
|
20
|
+
/** Allow a source to point at its own holder (e.g. self-animated entities). */
|
|
21
|
+
readonly allowSelf?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export type RelationshipRole = {
|
|
24
|
+
readonly kind: 'source';
|
|
25
|
+
readonly target: Component<string, ComponentSchema>;
|
|
26
|
+
readonly sourceField: string;
|
|
27
|
+
readonly targetField: string;
|
|
28
|
+
readonly exclusive: boolean;
|
|
29
|
+
readonly linkedSpawn: boolean;
|
|
30
|
+
readonly allowSelf: boolean;
|
|
31
|
+
} | {
|
|
32
|
+
readonly kind: 'target';
|
|
33
|
+
readonly source: Component<string, ComponentSchema>;
|
|
34
|
+
readonly sourceField: string;
|
|
35
|
+
readonly targetField: string;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Declare both sides of a relationship in one closed operation. The source is
|
|
39
|
+
* the only writable relationship component; its target is a materialized,
|
|
40
|
+
* engine-maintained reverse list.
|
|
41
|
+
*/
|
|
42
|
+
export declare function defineRelationship<const S extends string, const SF extends string, const T extends string, const TF extends string>(options: RelationshipOptions & {
|
|
43
|
+
readonly sourceName: S;
|
|
44
|
+
readonly sourceField: SF;
|
|
45
|
+
readonly targetName: T;
|
|
46
|
+
readonly targetField: TF;
|
|
47
|
+
}): {
|
|
48
|
+
readonly source: Component<S, {
|
|
49
|
+
[K in SF]: 'entity';
|
|
50
|
+
}>;
|
|
51
|
+
readonly target: RelationshipTargetComponent<Component<T, {
|
|
52
|
+
[K in TF]: 'array<entity>';
|
|
53
|
+
}>>;
|
|
54
|
+
};
|
|
55
|
+
export declare function relationshipRole(component: Component): RelationshipRole | undefined;
|
|
56
|
+
/** Return the materialized target token owned by a source relationship. */
|
|
57
|
+
export declare function relationshipMirror(component: Component): Component | undefined;
|
|
58
|
+
/** Return the source token owned by a materialized relationship target. */
|
|
59
|
+
export declare function relationshipSource(component: Component): Component | undefined;
|
|
60
|
+
export declare function isRelationshipTarget(component: Component): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Backpointer index for the materialized reverse lists stored by World.
|
|
63
|
+
* The target component array is the one authoritative read list; this index
|
|
64
|
+
* stores only source-to-target locations for O(1) swap-remove bookkeeping.
|
|
65
|
+
*/
|
|
66
|
+
export declare class RelationshipIndex {
|
|
67
|
+
private readonly slots;
|
|
68
|
+
private epochValue;
|
|
69
|
+
get epoch(): number;
|
|
70
|
+
attach(source: EntityHandle, target: EntityHandle, slot: number): number;
|
|
71
|
+
detach(source: EntityHandle): boolean;
|
|
72
|
+
reparent(source: EntityHandle, target: EntityHandle, slot: number): number;
|
|
73
|
+
slotOf(source: EntityHandle): number | undefined;
|
|
74
|
+
targetOf(source: EntityHandle): EntityHandle | undefined;
|
|
75
|
+
/** Bind the source that swap-remove moved into `slot`. */
|
|
76
|
+
updateSlot(source: EntityHandle, target: EntityHandle, slot: number): void;
|
|
77
|
+
/** Cold recovery path only: rebuild from R source records. */
|
|
78
|
+
recover(records: Iterable<readonly [EntityHandle, EntityHandle]>): void;
|
|
79
|
+
}
|
|
80
|
+
export {};
|
|
81
|
+
//# sourceMappingURL=relationship-index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationship-index.d.ts","sourceRoot":"","sources":["../src/relationship-index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/** Internal resource storage. */
|
|
2
|
+
export interface ResourceEntry {
|
|
3
|
+
value: unknown;
|
|
4
|
+
added: number;
|
|
5
|
+
changed: number;
|
|
6
|
+
}
|
|
7
|
+
export interface ResourceStore {
|
|
8
|
+
readonly entries: Map<string, ResourceEntry>;
|
|
9
|
+
}
|
|
10
|
+
/** Create a fresh resource store. */
|
|
11
|
+
export declare function createResourceStore(): ResourceStore;
|
|
12
|
+
/**
|
|
13
|
+
* Insert or overwrite a resource (idempotent, E-13).
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { createResourceStore, insertResource, type ResourceStore } from './resource';
|
|
18
|
+
*
|
|
19
|
+
* const store: ResourceStore = createResourceStore();
|
|
20
|
+
* insertResource(store, 'health', 100);
|
|
21
|
+
* // overwriting is idempotent (no error / no duplicate slot):
|
|
22
|
+
* insertResource(store, 'health', 95);
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function insertResource<T>(store: ResourceStore, key: string, value: T, epoch?: number): void;
|
|
26
|
+
/**
|
|
27
|
+
* Get a resource by key.
|
|
28
|
+
* @throws ResourceNotFoundError if key does not exist (E-14).
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* import { getResource, insertResource, type ResourceStore } from './resource';
|
|
33
|
+
*
|
|
34
|
+
* declare const store: ResourceStore;
|
|
35
|
+
* insertResource(store, 'health', 100);
|
|
36
|
+
* const hp = getResource<number>(store, 'health');
|
|
37
|
+
* // hp === 100; throws ResourceNotFoundError on missing key (charter proposition 4)
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function getResource<T>(store: ResourceStore, key: string): T;
|
|
41
|
+
/**
|
|
42
|
+
* Check if a resource exists.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```ts
|
|
46
|
+
* import { hasResource, insertResource, type ResourceStore } from './resource';
|
|
47
|
+
*
|
|
48
|
+
* declare const store: ResourceStore;
|
|
49
|
+
* insertResource(store, 'health', 100);
|
|
50
|
+
* if (hasResource(store, 'health')) {
|
|
51
|
+
* // guarded access avoids ResourceNotFoundError from getResource
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function hasResource(store: ResourceStore, key: string): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Remove a resource by key.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* import { hasResource, insertResource, removeResource, type ResourceStore } from './resource';
|
|
62
|
+
*
|
|
63
|
+
* declare const store: ResourceStore;
|
|
64
|
+
* insertResource(store, 'health', 100);
|
|
65
|
+
* removeResource(store, 'health');
|
|
66
|
+
* // hasResource(store, 'health') === false; idempotent on missing keys
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export declare function removeResource(store: ResourceStore, key: string): boolean;
|
|
70
|
+
//# sourceMappingURL=resource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAWA,iCAAiC;AACjC,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CAC9C;AAED,qCAAqC;AACrC,wBAAgB,mBAAmB,IAAI,aAAa,CAEnD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,SAAI,GAAG,IAAI,CAQ9F;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,CAMnE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAEzE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Nominal label for one of the World-owned schedules.
|
|
3
|
+
*
|
|
4
|
+
* Worlds expose the built-in tokens below. A token is both a registration
|
|
5
|
+
* scope and, for FixedUpdate, the intrinsic Update ordering anchor.
|
|
6
|
+
*/
|
|
7
|
+
export interface ScheduleToken {
|
|
8
|
+
readonly name: string;
|
|
9
|
+
}
|
|
10
|
+
export type ScheduleName = 'Update' | 'FixedUpdate';
|
|
11
|
+
/** Variable-rate World schedule. */
|
|
12
|
+
export declare const Update: ScheduleToken;
|
|
13
|
+
/** Fixed-rate World schedule and the intrinsic Update ordering anchor. */
|
|
14
|
+
export declare const FixedUpdate: ScheduleToken;
|
|
15
|
+
export declare function isScheduleToken(value: unknown): value is ScheduleToken;
|
|
16
|
+
//# sourceMappingURL=schedule-token.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule-token.d.ts","sourceRoot":"","sources":["../src/schedule-token.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,aAAa,CAAC;AAuBpD,oCAAoC;AACpC,eAAO,MAAM,MAAM,eAAgC,CAAC;AACpD,0EAA0E;AAC1E,eAAO,MAAM,WAAW,eAAqC,CAAC;AAC9D,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,aAAa,CAEtE"}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { type Result } from '@forgeax/engine-types';
|
|
2
|
+
import { type CommandBuffer } from './commands';
|
|
3
|
+
import type { Component } from './component';
|
|
4
|
+
import { ScheduleMutationError, type SystemSetNotRegisteredError } from './errors';
|
|
5
|
+
import type { Query, QueryDescriptor } from './query/query';
|
|
6
|
+
import type { ScheduleToken } from './schedule-token';
|
|
7
|
+
import type { World } from './world';
|
|
8
|
+
type SystemQueryResults<Qs extends ReadonlyArray<QueryDescriptor> = ReadonlyArray<QueryDescriptor>> = {
|
|
9
|
+
[K in keyof Qs]: Qs[K] extends QueryDescriptor<infer R extends ReadonlyArray<Component>, infer W extends ReadonlyArray<Component>, infer O extends ReadonlyArray<Component>> ? Query<NoInfer<R>, NoInfer<W>, NoInfer<O>> : Query;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* System descriptor passed to `world.addSystem` — `fn` receives one persistent
|
|
13
|
+
* executable Query per descriptor, mapped over `Qs` without casts.
|
|
14
|
+
*
|
|
15
|
+
* `Qs` is the tuple of query descriptors; defaults to
|
|
16
|
+
* `readonly QueryDescriptor[]` so non-generic call sites stay zero-modification
|
|
17
|
+
* (KD-5). The `fn` first parameter is mapped over `Qs` so each
|
|
18
|
+
* `queryResults[i]` recovers its own row access roles (S-5, KD-2).
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* // Single-query system — row access recovers each component schema.
|
|
23
|
+
* import { defineComponent, World } from '@forgeax/engine-ecs';
|
|
24
|
+
*
|
|
25
|
+
* const Position = defineComponent('Position', { x: 'f32', y: 'f32' });
|
|
26
|
+
* const Velocity = defineComponent('Velocity', { dx: 'f32', dy: 'f32' });
|
|
27
|
+
*
|
|
28
|
+
* const world = new World();
|
|
29
|
+
* world.addSystem(Update, {
|
|
30
|
+
* name: 'movement',
|
|
31
|
+
* queries: [{ write: [Position], read: [Velocity] }],
|
|
32
|
+
* fn: (_world, queryResults, _commands) => {
|
|
33
|
+
* for (const row of queryResults[0]) {
|
|
34
|
+
* row.mut(Position).x += row.get(Velocity).dx;
|
|
35
|
+
* }
|
|
36
|
+
* },
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* // Multi-query system — each queryResults[i] keeps its own row shape.
|
|
43
|
+
* const Health = defineComponent('Health', { hp: 'f32' });
|
|
44
|
+
* world.addSystem(Update, {
|
|
45
|
+
* name: 'multi',
|
|
46
|
+
* queries: [{ read: [Position] }, { read: [Health] }],
|
|
47
|
+
* fn: (_world, queryResults) => {
|
|
48
|
+
* for (const row of queryResults[0]) void row.get(Position).x;
|
|
49
|
+
* for (const row of queryResults[1]) void row.get(Health).hp;
|
|
50
|
+
* },
|
|
51
|
+
* });
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* // Commands-only system — `queries: []` is a legal form; fn receives `[]`.
|
|
57
|
+
* world.addSystem(Update, {
|
|
58
|
+
* name: 'spawner',
|
|
59
|
+
* queries: [],
|
|
60
|
+
* fn: (_world, _queryResults, commands) => {
|
|
61
|
+
* commands.spawn({ component: Position, data: { x: 0, y: 0 } });
|
|
62
|
+
* },
|
|
63
|
+
* });
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export interface SystemDescriptor<Qs extends ReadonlyArray<QueryDescriptor> = ReadonlyArray<QueryDescriptor>> {
|
|
67
|
+
/** Unique system name (used for before/after references). */
|
|
68
|
+
readonly name: string;
|
|
69
|
+
/** Query descriptors this system reads. */
|
|
70
|
+
readonly queries: Qs;
|
|
71
|
+
/**
|
|
72
|
+
* System function — receives the World, resolved query results, and commands.
|
|
73
|
+
*
|
|
74
|
+
* @param world The owning World — read resources (`world.getResource(KEY)`),
|
|
75
|
+
* resolve components by name, etc. without closure capture.
|
|
76
|
+
* @param queryResults Mapped over `Qs`: each entry is a persistent Query.
|
|
77
|
+
* @param commands Deferred-mutation buffer (flushed after the system).
|
|
78
|
+
*/
|
|
79
|
+
readonly fn: (world: World, queryResults: SystemQueryResults<Qs>, commands: CommandBuffer) => void | unknown;
|
|
80
|
+
/** Run this system after named systems or the FixedUpdate anchor. */
|
|
81
|
+
readonly after?: ReadonlyArray<string | ScheduleToken>;
|
|
82
|
+
/** Run this system before named systems or the FixedUpdate anchor. */
|
|
83
|
+
readonly before?: ReadonlyArray<string | ScheduleToken>;
|
|
84
|
+
/**
|
|
85
|
+
* Run condition. Evaluated each frame after ParamValidation passes (tag
|
|
86
|
+
* 'ok') and before query iteration. Returning `false` skips the system silently —
|
|
87
|
+
* no query runs, no fn call, no state added (plan-strategy D-8). Omitting it
|
|
88
|
+
* (undefined) always runs the system.
|
|
89
|
+
*/
|
|
90
|
+
readonly runIf?: (world: World) => boolean;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* A registered system token returned by {@link defineSystem}. Structurally the
|
|
94
|
+
* frozen {@link SystemDescriptor} itself (plan-strategy D-6 — "define ==
|
|
95
|
+
* register"). `world.addSystem(handle)` consumes it directly; the generic `Qs`
|
|
96
|
+
* flows through so the `fn` per-query row access shapes survive (S-5).
|
|
97
|
+
*/
|
|
98
|
+
export type SystemHandle<Qs extends ReadonlyArray<QueryDescriptor> = ReadonlyArray<QueryDescriptor>> = SystemDescriptor<Qs>;
|
|
99
|
+
/** Internal system record with registration index. */
|
|
100
|
+
interface SystemRecord {
|
|
101
|
+
descriptor: SystemDescriptor;
|
|
102
|
+
/** Registration order index (for tie-breaking). */
|
|
103
|
+
registrationIndex: number;
|
|
104
|
+
/** Cached executable Queries, one per descriptor. */
|
|
105
|
+
queries: Query[] | null;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Per-set record in the Schedule. Created lazily on first addSystems /
|
|
109
|
+
* addSystems call for a given set name.
|
|
110
|
+
*/
|
|
111
|
+
export interface SetRecord {
|
|
112
|
+
/** Member system names (insertion-ordered, Set preserves add order). */
|
|
113
|
+
readonly members: Set<string>;
|
|
114
|
+
/** Snapshot of runIf from the defining token. */
|
|
115
|
+
readonly runIf: ((world: import('./world').World) => boolean) | undefined;
|
|
116
|
+
/** Snapshot of chained from the defining token. */
|
|
117
|
+
readonly chained: boolean;
|
|
118
|
+
}
|
|
119
|
+
/** The Schedule manages system registration, DAG sorting, and execution. */
|
|
120
|
+
export interface Schedule {
|
|
121
|
+
/** Owning token for scope-aware diagnostics. */
|
|
122
|
+
readonly token: ScheduleToken;
|
|
123
|
+
/** All registered systems by name. */
|
|
124
|
+
systems: Map<string, SystemRecord>;
|
|
125
|
+
/** Set records keyed by set name. Created lazily. */
|
|
126
|
+
sets: Map<string, SetRecord>;
|
|
127
|
+
/** Next registration index. */
|
|
128
|
+
nextIndex: number;
|
|
129
|
+
/** Whether the sorted order is stale. */
|
|
130
|
+
dirty: boolean;
|
|
131
|
+
/** Sorted system names after buildSchedule(). */
|
|
132
|
+
sortedOrder: string[];
|
|
133
|
+
/** Direct predecessor names derived while the DAG is built. */
|
|
134
|
+
predecessors: Map<string, Set<string>>;
|
|
135
|
+
}
|
|
136
|
+
/** Create a fresh Schedule. */
|
|
137
|
+
export declare function createSchedule(token: ScheduleToken): Schedule;
|
|
138
|
+
/**
|
|
139
|
+
* Register a system. Marks schedule as dirty.
|
|
140
|
+
* Queries are lazily initialized on first runSchedule.
|
|
141
|
+
*
|
|
142
|
+
* `const Qs` locks the `queries` tuple at the call site so `fn`'s first
|
|
143
|
+
* parameter recovers per-query row shapes without `as const` annotations
|
|
144
|
+
* (S-5, KD-2). `SystemRecord` itself is intentionally non-generic — the
|
|
145
|
+
* heterogeneous `Qs` cannot be expressed inside the systems Map (KD-3).
|
|
146
|
+
*/
|
|
147
|
+
export declare function addSystem<const Qs extends ReadonlyArray<QueryDescriptor>>(schedule: Schedule, descriptor: SystemDescriptor<Qs>): void;
|
|
148
|
+
/**
|
|
149
|
+
* Define a system at module level. Returns a frozen {@link SystemHandle} token
|
|
150
|
+
* (the descriptor itself); executable registration is World-local.
|
|
151
|
+
*
|
|
152
|
+
* `world.addSystem(handle)` consumes the token directly — no by-name overload
|
|
153
|
+
* (OOS-8). Duplicate names are resolved by the owning World schedule.
|
|
154
|
+
*
|
|
155
|
+
* `const Qs` locks the `queries` tuple so `fn`'s query-results parameter
|
|
156
|
+
* recovers per-query row access shapes without `as const` (S-5).
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```ts
|
|
160
|
+
* const Move = defineSystem({
|
|
161
|
+
* name: 'movement',
|
|
162
|
+
* queries: [{ with: [Position, Velocity] }],
|
|
163
|
+
* fn: (_world, queryResults) => { ... },
|
|
164
|
+
* });
|
|
165
|
+
* world.addSystem(Move);
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
export declare function defineSystem<const Qs extends ReadonlyArray<QueryDescriptor>>(descriptor: SystemDescriptor<Qs>): SystemHandle<Qs>;
|
|
169
|
+
/**
|
|
170
|
+
*/
|
|
171
|
+
/** Brand symbol for {@link SystemSet}. Declared (not runtime-initialised) so
|
|
172
|
+
* the token interface carries nominal identity without a runtime allocation.
|
|
173
|
+
* Mirrors the `FORGEAX_STATE_BRAND` pattern in `@forgeax/engine-state`. */
|
|
174
|
+
declare const FORGEAX_SYSTEM_SET_BRAND: unique symbol;
|
|
175
|
+
/**
|
|
176
|
+
* Opaque branded type for system-set tokens.
|
|
177
|
+
*
|
|
178
|
+
* Use {@link defineSystemSet} to create a token; never construct manually.
|
|
179
|
+
* The {@link __forgeaxSystemSet} brand prevents plain-object assignment and
|
|
180
|
+
* enables TypeScript narrowing at the two mutation entry points.
|
|
181
|
+
*/
|
|
182
|
+
export interface SystemSet {
|
|
183
|
+
/** Brand — prevents structural compatibility with plain objects. */
|
|
184
|
+
readonly __forgeaxSystemSet: typeof FORGEAX_SYSTEM_SET_BRAND;
|
|
185
|
+
/** The user-supplied set name. */
|
|
186
|
+
readonly name: string;
|
|
187
|
+
/** Optional per-frame run condition. Consumed by M3 condition gate. */
|
|
188
|
+
readonly runIf?: (world: import('./world').World) => boolean;
|
|
189
|
+
/** Whether this set forms a sequential chain (M2). */
|
|
190
|
+
readonly chained?: boolean;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Define a system set at module level. Returns a frozen branded token and
|
|
194
|
+
* keeps membership in the World-local Schedule.
|
|
195
|
+
*
|
|
196
|
+
* Duplicate names are independent tokens; the owning World decides membership.
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```ts
|
|
200
|
+
* const GameplaySet = defineSystemSet({ name: 'gameplay', runIf: (w) => !w.getResource<boolean>('paused') });
|
|
201
|
+
* const OrderedSet = defineSystemSet({ name: 'ordered', chained: true });
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
export declare function defineSystemSet(opts: {
|
|
205
|
+
readonly name: string;
|
|
206
|
+
readonly runIf?: (world: import('./world').World) => boolean;
|
|
207
|
+
readonly chained?: boolean;
|
|
208
|
+
}): SystemSet;
|
|
209
|
+
/**
|
|
210
|
+
/**
|
|
211
|
+
* Validate every token in `tokens` for local structural validity.
|
|
212
|
+
* Returns `ok(undefined)` for a structurally valid token and reports an empty
|
|
213
|
+
* token name as a structured registration error.
|
|
214
|
+
*
|
|
215
|
+
* Does not write any Schedule state — callers consume the `Result` and proceed
|
|
216
|
+
* only on `ok`.
|
|
217
|
+
*/
|
|
218
|
+
export declare function validateSystemSetTokens(tokens: readonly SystemSet[]): Result<void, SystemSetNotRegisteredError>;
|
|
219
|
+
/**
|
|
220
|
+
* Remove a registered system by name (M2 — plan-strategy D-3).
|
|
221
|
+
*
|
|
222
|
+
* Drops the entry from `schedule.systems` and marks the schedule dirty so the
|
|
223
|
+
* next `runSchedule` rebuilds the sorted order via Kahn topo. Cycle detection
|
|
224
|
+
* already happens inside `buildSchedule`, so a removal that breaks an unrelated
|
|
225
|
+
* `before/after` reference simply skips the unknown name (existing behaviour).
|
|
226
|
+
*
|
|
227
|
+
* Failure: name not registered → `Result.err(ScheduleMutationError)` with
|
|
228
|
+
* `.code = 'system-before-unknown'` and `.detail.candidates` carrying the
|
|
229
|
+
* registered names for AI-friendly typo recovery.
|
|
230
|
+
*/
|
|
231
|
+
export declare function removeSystem(schedule: Schedule, name: string): Result<void, ScheduleMutationError>;
|
|
232
|
+
/**
|
|
233
|
+
* Replace a registered system in-place (M2 — plan-strategy D-3 atomic semantics).
|
|
234
|
+
*
|
|
235
|
+
* Overwrites the `descriptor` field of the existing `SystemRecord` while
|
|
236
|
+
* keeping `registrationIndex` and the `Map` slot identical, so all `before /
|
|
237
|
+
* after` edges that reference this name remain bound to the same slot. Marks
|
|
238
|
+
* the schedule dirty: the next `runSchedule` re-sorts.
|
|
239
|
+
*
|
|
240
|
+
* Failure: name not registered → `Result.err(ScheduleMutationError)` with
|
|
241
|
+
* `.code = 'system-before-unknown'`.
|
|
242
|
+
*/
|
|
243
|
+
export declare function replaceSystem<const Qs extends ReadonlyArray<QueryDescriptor>>(schedule: Schedule, name: string, descriptor: SystemDescriptor<Qs>): Result<void, ScheduleMutationError>;
|
|
244
|
+
/**
|
|
245
|
+
* Batch-register systems to a set. Validates the set token before writing.
|
|
246
|
+
*
|
|
247
|
+
* - First call for a system name: registers via the existing `addSystem` path.
|
|
248
|
+
* - Subsequent calls: only adds the system name to the set's members (dedup).
|
|
249
|
+
* - `runIf` / `chained` are snapshotted from the token into the SetRecord on
|
|
250
|
+
* first encounter.
|
|
251
|
+
*
|
|
252
|
+
* Returns `Result.err` with `SystemSetNotRegisteredError` if the set token
|
|
253
|
+
* fails identity validation.
|
|
254
|
+
*/
|
|
255
|
+
export declare function addSystems<const Qs extends ReadonlyArray<QueryDescriptor>>(schedule: Schedule, set: SystemSet, systems: ReadonlyArray<SystemDescriptor<Qs>>): Result<void, SystemSetNotRegisteredError>;
|
|
256
|
+
/**
|
|
257
|
+
* Build the sorted execution order via Kahn's topological sort.
|
|
258
|
+
* Throws CyclicDependencyError if a cycle is detected.
|
|
259
|
+
*
|
|
260
|
+
* @returns sorted system names
|
|
261
|
+
*/
|
|
262
|
+
export declare function buildSchedule(schedule: Schedule): string[];
|
|
263
|
+
/**
|
|
264
|
+
* Execute one schedule with a terminalization guard. Query construction,
|
|
265
|
+
* run-if evaluation, DAG compilation, and command draining may all throw an
|
|
266
|
+
* unexpected error; every still-open buffer is nevertheless aborted before the
|
|
267
|
+
* error reaches World.update.
|
|
268
|
+
*/
|
|
269
|
+
export declare function runSchedule(schedule: Schedule, world: World, selectedNames?: readonly string[], commandsBySystem?: Map<string, import("./commands").CommandBufferImpl>, finalDrain?: boolean): void;
|
|
270
|
+
export {};
|
|
271
|
+
//# sourceMappingURL=schedule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../src/schedule.ts"],"names":[],"mappings":"AAKA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,KAAK,aAAa,EAAsC,MAAM,YAAY,CAAC;AACpF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAEL,qBAAqB,EAErB,KAAK,2BAA2B,EAEjC,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAK5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAOrC,KAAK,kBAAkB,CACrB,EAAE,SAAS,aAAa,CAAC,eAAe,CAAC,GAAG,aAAa,CAAC,eAAe,CAAC,IACxE;KACD,CAAC,IAAI,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,eAAe,CAC5C,MAAM,CAAC,SAAS,aAAa,CAAC,SAAS,CAAC,EACxC,MAAM,CAAC,SAAS,aAAa,CAAC,SAAS,CAAC,EACxC,MAAM,CAAC,SAAS,aAAa,CAAC,SAAS,CAAC,CACzC,GACG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,GACzC,KAAK;CACV,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,MAAM,WAAW,gBAAgB,CAC/B,EAAE,SAAS,aAAa,CAAC,eAAe,CAAC,GAAG,aAAa,CAAC,eAAe,CAAC;IAE1E,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;IACrB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,EAAE,CACX,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,kBAAkB,CAAC,EAAE,CAAC,EACpC,QAAQ,EAAE,aAAa,KACpB,IAAI,GAAG,OAAO,CAAC;IACpB,qEAAqE;IACrE,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,MAAM,GAAG,aAAa,CAAC,CAAC;IACvD,sEAAsE;IACtE,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC,MAAM,GAAG,aAAa,CAAC,CAAC;IACxD;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC;CAC5C;AAED;;;;;GAKG;AACH,MAAM,MAAM,YAAY,CACtB,EAAE,SAAS,aAAa,CAAC,eAAe,CAAC,GAAG,aAAa,CAAC,eAAe,CAAC,IACxE,gBAAgB,CAAC,EAAE,CAAC,CAAC;AAEzB,sDAAsD;AACtD,UAAU,YAAY;IACpB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,mDAAmD;IACnD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qDAAqD;IACrD,OAAO,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;CACzB;AAMD;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,iDAAiD;IACjD,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,SAAS,EAAE,KAAK,KAAK,OAAO,CAAC,GAAG,SAAS,CAAC;IAC1E,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,4EAA4E;AAC5E,MAAM,WAAW,QAAQ;IACvB,gDAAgD;IAChD,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,sCAAsC;IACtC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACnC,qDAAqD;IACrD,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC7B,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,KAAK,EAAE,OAAO,CAAC;IACf,iDAAiD;IACjD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,+DAA+D;IAC/D,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;CACxC;AAED,+BAA+B;AAC/B,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,QAAQ,CAU7D;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,KAAK,CAAC,EAAE,SAAS,aAAa,CAAC,eAAe,CAAC,EACvE,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,gBAAgB,CAAC,EAAE,CAAC,GAC/B,IAAI,CAQN;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAAC,KAAK,CAAC,EAAE,SAAS,aAAa,CAAC,eAAe,CAAC,EAC1E,UAAU,EAAE,gBAAgB,CAAC,EAAE,CAAC,GAC/B,YAAY,CAAC,EAAE,CAAC,CAGlB;AAED;GACG;AAKH;;2EAE2E;AAC3E,OAAO,CAAC,MAAM,wBAAwB,EAAE,OAAO,MAAM,CAAC;AAEtD;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,oEAAoE;IACpE,QAAQ,CAAC,kBAAkB,EAAE,OAAO,wBAAwB,CAAC;IAC7D,kCAAkC;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,SAAS,EAAE,KAAK,KAAK,OAAO,CAAC;IAC7D,sDAAsD;IACtD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,SAAS,EAAE,KAAK,KAAK,OAAO,CAAC;IAC7D,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B,GAAG,SAAS,CAaZ;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,SAAS,EAAE,GAC3B,MAAM,CAAC,IAAI,EAAE,2BAA2B,CAAC,CAO3C;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,GACX,MAAM,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAkBrC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,KAAK,CAAC,EAAE,SAAS,aAAa,CAAC,eAAe,CAAC,EAC3E,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,gBAAgB,CAAC,EAAE,CAAC,GAC/B,MAAM,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAiBrC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,KAAK,CAAC,EAAE,SAAS,aAAa,CAAC,eAAe,CAAC,EACxE,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,SAAS,EACd,OAAO,EAAE,aAAa,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,GAC3C,MAAM,CAAC,IAAI,EAAE,2BAA2B,CAAC,CA6B3C;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,EAAE,CAiH1D;AAmQD;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,KAAK,EACZ,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,EACjC,gBAAgB,sDAA4D,EAC5E,UAAU,UAAO,GAChB,IAAI,CAYN"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type { Handle } from '@forgeax/engine-types';
|
|
2
|
+
import { type Result } from '@forgeax/engine-types';
|
|
3
|
+
import { BuiltinSlotNotOwnedError, SharedRefDoubleReleaseError, SharedRefReleasedError, SharedRefStaleError } from './errors';
|
|
4
|
+
export interface SharedRefMutation {
|
|
5
|
+
readonly epoch: number;
|
|
6
|
+
readonly handle: number;
|
|
7
|
+
}
|
|
8
|
+
export interface SharedRefReleaseEvidence {
|
|
9
|
+
readonly payload: unknown;
|
|
10
|
+
readonly refcount: 0;
|
|
11
|
+
readonly generation: number;
|
|
12
|
+
readonly evidence: 'released';
|
|
13
|
+
}
|
|
14
|
+
export type SharedRefMutationRead = {
|
|
15
|
+
readonly status: 'ok';
|
|
16
|
+
readonly cursor: number;
|
|
17
|
+
readonly records: readonly SharedRefMutation[];
|
|
18
|
+
} | {
|
|
19
|
+
readonly status: 'overflow';
|
|
20
|
+
readonly cursor: number;
|
|
21
|
+
readonly oldestAvailable: number;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Reference-counted store for ECS-aware `Handle<T, 'shared'>` lifecycles.
|
|
25
|
+
*
|
|
26
|
+
* The producer (typically AssetRegistry) calls `alloc` once and owns the
|
|
27
|
+
* "alloc-grant" rc=1; consumers (ECS schema fields, external systems) call
|
|
28
|
+
* `retain` on each new holder and `release` when the holder drops. When rc
|
|
29
|
+
* transitions 1 -> 0 the store publishes one structured release-evidence
|
|
30
|
+
* record; it does not invoke a user callback or own payload disposal.
|
|
31
|
+
*
|
|
32
|
+
* D-15: manages ONLY user-tier slots (`slot >= BUILTIN_BASE`). Builtin slots
|
|
33
|
+
* (`< BUILTIN_BASE`) fail-fast with `BuiltinSlotNotOwnedError`.
|
|
34
|
+
*
|
|
35
|
+
* Public API:
|
|
36
|
+
* - alloc(target, payload) -> Handle<T, 'shared'> (rc=1)
|
|
37
|
+
* - intern(target, payload) -> stable producer handle per target + object identity
|
|
38
|
+
* - resolve(handle) -> Result<T, SharedRefReleasedError | SharedRefStaleError | BuiltinSlotNotOwnedError>
|
|
39
|
+
* - markChanged(handle) -> Result<void, SharedRefReleasedError | SharedRefStaleError | BuiltinSlotNotOwnedError>
|
|
40
|
+
* - getMutationEpoch() -> monotonic payload-mutation cursor
|
|
41
|
+
* - retain(handle) -> Result<void, SharedRefReleasedError | SharedRefStaleError | BuiltinSlotNotOwnedError>
|
|
42
|
+
* - release(handle) -> Result<release evidence | undefined, ...>
|
|
43
|
+
* - refcount(handle) -> number (0 == released; debug + tests)
|
|
44
|
+
* - _liveCount() -> live slot count (debug + inspector)
|
|
45
|
+
*/
|
|
46
|
+
export declare class SharedRefStore {
|
|
47
|
+
private readonly payloads;
|
|
48
|
+
private readonly refcounts;
|
|
49
|
+
private readonly freeSlots;
|
|
50
|
+
private readonly internedByTarget;
|
|
51
|
+
private readonly internedKeys;
|
|
52
|
+
private nextSlot;
|
|
53
|
+
private mutationEpoch;
|
|
54
|
+
private readonly mutationJournal;
|
|
55
|
+
private readonly releaseJournal;
|
|
56
|
+
/**
|
|
57
|
+
* Generation table indexed by slot (D-6). Each entry tracks the current
|
|
58
|
+
* generation for the slot — written to during alloc (welded into the
|
|
59
|
+
* returned handle via pack) and incremented on release (M4).
|
|
60
|
+
*
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
63
|
+
private readonly _generations;
|
|
64
|
+
/**
|
|
65
|
+
* Allocate a fresh shared handle for `payload`, branded against `target`.
|
|
66
|
+
* Refcount starts at 1 (the alloc-grant). Nullish payloads are rejected
|
|
67
|
+
* before a slot or free-list is touched.
|
|
68
|
+
*
|
|
69
|
+
* The returned handle carries a generation tag welded via codec.pack
|
|
70
|
+
* (D-8, OOS-2): first allocation gen=0 (AC-06), reused slot gen = the
|
|
71
|
+
* current generation from _generations[slot]. The toShared brand cast
|
|
72
|
+
* happens internally — external callers no longer construct Handle<...>
|
|
73
|
+
* directly.
|
|
74
|
+
*
|
|
75
|
+
* Minted slots are user-tier (`>= BUILTIN_BASE`); builtin slots are never
|
|
76
|
+
* produced here (D-15).
|
|
77
|
+
*/
|
|
78
|
+
alloc<Target extends string, T = unknown>(target: Target, payload: T): Handle<Target, 'shared'>;
|
|
79
|
+
/**
|
|
80
|
+
* Return the idempotent producer handle for one object payload in this
|
|
81
|
+
* store. Identity includes `target`, so the same object branded for two
|
|
82
|
+
* asset kinds does not alias.
|
|
83
|
+
*
|
|
84
|
+
* A cache hit deliberately does not retain: this is one producer grant,
|
|
85
|
+
* discovered repeatedly by an asset catalogue. Actual holders retain and
|
|
86
|
+
* release through the ECS write barrier. Callers needing independent
|
|
87
|
+
* grants or a per-handle deleter must use {@link alloc}.
|
|
88
|
+
*/
|
|
89
|
+
intern<Target extends string, T extends object>(target: Target, payload: T): Handle<Target, 'shared'>;
|
|
90
|
+
/**
|
|
91
|
+
* Look up `payload` by handle. Returns `err(shared-ref-released)` when
|
|
92
|
+
* the handle's slot has no live payload (rc reached 0, no re-alloc has
|
|
93
|
+
* filled the slot); `err(builtin-slot-not-owned)` for a builtin slot.
|
|
94
|
+
*
|
|
95
|
+
* §contract - mirrors UniqueRefStore: a stale handle whose slot has been
|
|
96
|
+
* released and re-allocated returns `err(shared-ref-stale)` - the handle's
|
|
97
|
+
* welded generation no longer matches `_generations[slot]`. The gen check
|
|
98
|
+
* runs before payload lookup, so stale-by-reuse is caught deterministically.
|
|
99
|
+
*/
|
|
100
|
+
resolve<Target extends string, T = unknown>(handle: Handle<Target, 'shared'>): Result<T, SharedRefReleasedError | SharedRefStaleError | BuiltinSlotNotOwnedError>;
|
|
101
|
+
/**
|
|
102
|
+
* Publish that a live payload was mutated in place. Consumers that retain
|
|
103
|
+
* projections of shared payload data compare the monotonic epoch and
|
|
104
|
+
* explicitly refresh instead of rescanning every payload each frame.
|
|
105
|
+
*/
|
|
106
|
+
markChanged<Target extends string>(handle: Handle<Target, 'shared'>): Result<void, SharedRefReleasedError | SharedRefStaleError | BuiltinSlotNotOwnedError>;
|
|
107
|
+
/** Current upper bound for explicitly published payload mutations. */
|
|
108
|
+
getMutationEpoch(): number;
|
|
109
|
+
/** Read exact changed handles after `cursor`; overflow requires consumer resync. */
|
|
110
|
+
readChangesSince(cursor: number): SharedRefMutationRead;
|
|
111
|
+
/**
|
|
112
|
+
* Increment the refcount of a live shared handle. Returns
|
|
113
|
+
* `err(shared-ref-released)` when the handle is not live - retain MUST
|
|
114
|
+
* NOT resurrect a released slot (charter P3 explicit failure; would
|
|
115
|
+
* defeat the rc=0 -> drop invariant); `err(builtin-slot-not-owned)` for a
|
|
116
|
+
* builtin slot.
|
|
117
|
+
*/
|
|
118
|
+
retain<Target extends string>(handle: Handle<Target, 'shared'>): Result<void, SharedRefReleasedError | SharedRefStaleError | BuiltinSlotNotOwnedError>;
|
|
119
|
+
/**
|
|
120
|
+
* Decrement the refcount. When rc transitions 1 -> 0, the slot is dropped
|
|
121
|
+
* and one structured release-evidence record is published. The evidence
|
|
122
|
+
* captures the payload, zero refcount, next generation and `released` marker
|
|
123
|
+
* after the store has removed the live slot.
|
|
124
|
+
*
|
|
125
|
+
* Returns `err(shared-ref-double-release, rc=0)` when the handle has
|
|
126
|
+
* already reached rc=0 (or was never live); `err(builtin-slot-not-owned)`
|
|
127
|
+
* for a builtin slot. AI users branch on `.code` and route the
|
|
128
|
+
* second-release log to Layer 3 ErrorHandler without aborting the despawn
|
|
129
|
+
* chain.
|
|
130
|
+
*/
|
|
131
|
+
release<Target extends string>(handle: Handle<Target, 'shared'>): Result<SharedRefReleaseEvidence | undefined, SharedRefDoubleReleaseError | SharedRefStaleError | BuiltinSlotNotOwnedError>;
|
|
132
|
+
/** Read the bounded release evidence owned by this store. */
|
|
133
|
+
readReleaseEvidence(): readonly SharedRefReleaseEvidence[];
|
|
134
|
+
/**
|
|
135
|
+
* Return the current refcount for `handle`. Returns 0 for a released
|
|
136
|
+
* (or never-allocated) slot. Primarily a debug + tests entry point;
|
|
137
|
+
* production code rarely reads rc directly (the rc=0 -> drop invariant
|
|
138
|
+
* is the surface AI users consume via release / the per-handle deleter).
|
|
139
|
+
*/
|
|
140
|
+
refcount<Target extends string>(handle: Handle<Target, 'shared'>): number;
|
|
141
|
+
/** @internal Diagnostic count of live slots. Exposed for tests + inspector. */
|
|
142
|
+
_liveCount(): number;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=shared-ref-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared-ref-store.d.ts","sourceRoot":"","sources":["../src/shared-ref-store.ts"],"names":[],"mappings":"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"}
|
package/dist/shared.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export type { KernelDispatchFailure, KernelDispatchResult, KernelDispatchSpan, SharedFieldView, SharedKernelDefinition, SharedKernelDispatch, SharedKernelEligibilityReason, SharedKernelExecutor, SharedKernelHandle, SharedSpanBinding, WorldExecutionHealth, } from './execution/shared-kernel';
|
|
2
|
+
export { bindSharedSpan, defineSharedKernel, isKernelDispatchFailure, isSharedSpan, SHARED_KERNEL_ELIGIBILITY_REASONS, SHARED_KERNEL_EXECUTOR_RESOURCE_KEY, sharedKernelEligibility, splitSharedSpan, } from './execution/shared-kernel';
|
|
3
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../src/shared.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,6BAA6B,EAC7B,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,uBAAuB,EACvB,YAAY,EACZ,iCAAiC,EACjC,mCAAmC,EACnC,uBAAuB,EACvB,eAAe,GAChB,MAAM,2BAA2B,CAAC"}
|