@sixb/core 0.1.2 → 0.1.4
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/actions/index.js +19 -17
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/worker.js +4 -4
- package/dist/actions/worker.js.map +1 -1
- package/dist/agents/adapters.d.ts +11 -1
- package/dist/agents/adapters.d.ts.map +1 -1
- package/dist/agents/context-compaction.d.ts +40 -0
- package/dist/agents/context-compaction.d.ts.map +1 -0
- package/dist/agents/context.js +1 -1
- package/dist/agents/errors.d.ts +1 -1
- package/dist/agents/errors.d.ts.map +1 -1
- package/dist/agents/execution.d.ts +3 -0
- package/dist/agents/execution.d.ts.map +1 -1
- package/dist/agents/ids.d.ts +2 -0
- package/dist/agents/ids.d.ts.map +1 -1
- package/dist/agents/index.d.ts +10 -6
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +51 -35
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/request.d.ts.map +1 -1
- package/dist/agents/streams.d.ts +17 -1
- package/dist/agents/streams.d.ts.map +1 -1
- package/dist/agents/streams.js +5 -3
- package/dist/agents/streams.js.map +1 -1
- package/dist/agents/thread-context-projection.d.ts +19 -0
- package/dist/agents/thread-context-projection.d.ts.map +1 -0
- package/dist/agents/tool-definition.d.ts.map +1 -1
- package/dist/agents/tool-result.d.ts +6 -0
- package/dist/agents/tool-result.d.ts.map +1 -0
- package/dist/agents/types.d.ts +46 -1
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/agents/validation.d.ts +2 -2
- package/dist/agents/validation.d.ts.map +1 -1
- package/dist/auth/index.js +11 -5
- package/dist/auth/index.js.map +1 -1
- package/dist/authorization/index.js +6 -2
- package/dist/authorization/index.js.map +1 -1
- package/dist/bootstrap/index.js +33 -31
- package/dist/bootstrap/index.js.map +1 -1
- package/dist/{chunk-ys1nse2v.js → chunk-1wk20wn3.js} +438 -246
- package/dist/{chunk-ys1nse2v.js.map → chunk-1wk20wn3.js.map} +11 -11
- package/dist/{chunk-sa4340y1.js → chunk-1yz3x65y.js} +7 -7
- package/dist/{chunk-gqdd7508.js → chunk-4rh2m6zg.js} +1 -1
- package/dist/{chunk-fmx1sz2h.js → chunk-72q2y8hn.js} +3 -3
- package/dist/{chunk-fmx1sz2h.js.map → chunk-72q2y8hn.js.map} +4 -4
- package/dist/{chunk-nnyp53zt.js → chunk-7gw7mepb.js} +259 -9
- package/dist/chunk-7gw7mepb.js.map +14 -0
- package/dist/{chunk-nten49ta.js → chunk-819wnjz8.js} +11 -5
- package/dist/chunk-819wnjz8.js.map +12 -0
- package/dist/chunk-96swp2wd.js +47 -0
- package/dist/chunk-96swp2wd.js.map +10 -0
- package/dist/{chunk-4x43bkbp.js → chunk-a09jx26t.js} +1 -1
- package/dist/{chunk-st4xgxey.js → chunk-afjpa2hs.js} +205 -48
- package/dist/chunk-afjpa2hs.js.map +45 -0
- package/dist/{chunk-0mbx247x.js → chunk-c43qr6s0.js} +427 -99
- package/dist/chunk-c43qr6s0.js.map +46 -0
- package/dist/{chunk-zg9yryhz.js → chunk-cbkm2vam.js} +3 -3
- package/dist/{chunk-57zpb99z.js → chunk-dm72y8wt.js} +26 -3
- package/dist/chunk-dm72y8wt.js.map +10 -0
- package/dist/chunk-drjqm1aa.js +913 -0
- package/dist/chunk-drjqm1aa.js.map +15 -0
- package/dist/chunk-dysw7nsm.js.map +1 -1
- package/dist/{chunk-8ryen3p3.js → chunk-f6erf2vv.js} +1 -1
- package/dist/{chunk-34bqh420.js → chunk-f83ka50g.js} +188 -44
- package/dist/chunk-f83ka50g.js.map +23 -0
- package/dist/{chunk-bct7hmfc.js → chunk-g13869yf.js} +3 -3
- package/dist/{chunk-0k4avqr2.js → chunk-hbeh8j9w.js} +2 -2
- package/dist/{chunk-qvybnnpe.js → chunk-nzw7sm3b.js} +2 -2
- package/dist/{chunk-k9pts48t.js → chunk-pn8n8sba.js} +16 -15
- package/dist/{chunk-k9pts48t.js.map → chunk-pn8n8sba.js.map} +3 -3
- package/dist/{chunk-63te770v.js → chunk-qewtks41.js} +8 -8
- package/dist/{chunk-63te770v.js.map → chunk-qewtks41.js.map} +2 -2
- package/dist/{chunk-85j5ybfj.js → chunk-rdeagz6b.js} +2 -2
- package/dist/{chunk-85j5ybfj.js.map → chunk-rdeagz6b.js.map} +3 -3
- package/dist/chunk-rhrbz7d4.js +36 -0
- package/dist/chunk-rhrbz7d4.js.map +10 -0
- package/dist/{chunk-bh6k3nc6.js → chunk-rs1wbvy6.js} +1 -1
- package/dist/{chunk-88ppkr54.js → chunk-rte5sm3z.js} +26 -2
- package/dist/chunk-rte5sm3z.js.map +12 -0
- package/dist/{chunk-n8herkry.js → chunk-s31d0qmq.js} +57 -20
- package/dist/{chunk-n8herkry.js.map → chunk-s31d0qmq.js.map} +8 -7
- package/dist/{chunk-7pc8b818.js → chunk-sxwk41qa.js} +1 -1
- package/dist/{chunk-663csy96.js → chunk-t0jjkep3.js} +2 -1
- package/dist/chunk-t0jjkep3.js.map +10 -0
- package/dist/{chunk-c6qd89g5.js → chunk-tek1qwgm.js} +6 -6
- package/dist/{chunk-c6qd89g5.js.map → chunk-tek1qwgm.js.map} +1 -1
- package/dist/{chunk-jaj13078.js → chunk-tkdscva6.js} +3 -33
- package/dist/{chunk-jaj13078.js.map → chunk-tkdscva6.js.map} +3 -4
- package/dist/{chunk-5egfka8j.js → chunk-tycbzedm.js} +2 -2
- package/dist/{chunk-g9t3kdtx.js → chunk-x2yw73hy.js} +1 -1
- package/dist/{chunk-57r1cpxx.js → chunk-xc7hq65b.js} +3 -2
- package/dist/{chunk-57r1cpxx.js.map → chunk-xc7hq65b.js.map} +3 -3
- package/dist/chunk-xdf9yswn.js +133 -0
- package/dist/chunk-xdf9yswn.js.map +11 -0
- package/dist/execution/agent.js +29 -27
- package/dist/execution/agent.js.map +1 -1
- package/dist/execution/primitive.js +29 -27
- package/dist/execution/primitive.js.map +2 -2
- package/dist/execution/request.js +30 -28
- package/dist/execution/request.js.map +2 -2
- package/dist/http/index.js +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +60 -58
- package/dist/index.js.map +1 -1
- package/dist/lake-storage/types.d.ts +2 -1
- package/dist/lake-storage/types.d.ts.map +1 -1
- package/dist/materialization/model.d.ts +4 -0
- package/dist/materialization/model.d.ts.map +1 -1
- package/dist/materializer/edits/apply.d.ts +6 -1
- package/dist/materializer/edits/apply.d.ts.map +1 -1
- package/dist/materializer/edits/working-state.d.ts +2 -0
- package/dist/materializer/edits/working-state.d.ts.map +1 -1
- package/dist/materializer/effective/resolve.d.ts +3 -1
- package/dist/materializer/effective/resolve.d.ts.map +1 -1
- package/dist/materializer/execution/work-records.d.ts.map +1 -1
- package/dist/materializer/index.js +19 -17
- package/dist/materializer/index.js.map +1 -1
- package/dist/materializer/projections/replacement-plan.d.ts.map +1 -1
- package/dist/materializer/shared/normalize.d.ts.map +1 -1
- package/dist/models/index.d.ts +40 -0
- package/dist/models/index.d.ts.map +1 -0
- package/dist/objects/execution.d.ts +6 -1
- package/dist/objects/execution.d.ts.map +1 -1
- package/dist/objects/index.js +21 -19
- package/dist/objects/index.js.map +1 -1
- package/dist/objects/link/endpoints.d.ts.map +1 -1
- package/dist/objects/query/executor.d.ts +1 -0
- package/dist/objects/query/executor.d.ts.map +1 -1
- package/dist/objects/query/explain.d.ts +1 -0
- package/dist/objects/query/explain.d.ts.map +1 -1
- package/dist/objects/query/index.d.ts +3 -1
- package/dist/objects/query/index.d.ts.map +1 -1
- package/dist/objects/query/index.js +30 -5
- package/dist/objects/query/index.js.map +1 -1
- package/dist/objects/query/ir.d.ts +14 -1
- package/dist/objects/query/ir.d.ts.map +1 -1
- package/dist/objects/query/links.d.ts +25 -0
- package/dist/objects/query/links.d.ts.map +1 -0
- package/dist/objects/query/normalize.d.ts.map +1 -1
- package/dist/objects/query/planner.d.ts.map +1 -1
- package/dist/objects/query/validate.d.ts +1 -0
- package/dist/objects/query/validate.d.ts.map +1 -1
- package/dist/pipelines/index.js +16 -15
- package/dist/pipelines/index.js.map +1 -1
- package/dist/projections/builders.d.ts +52 -10
- package/dist/projections/builders.d.ts.map +1 -1
- package/dist/projections/index.d.ts +2 -1
- package/dist/projections/index.d.ts.map +1 -1
- package/dist/projections/internal.d.ts +4 -1
- package/dist/projections/internal.d.ts.map +1 -1
- package/dist/projections/internal.js +22 -17
- package/dist/projections/internal.js.map +1 -1
- package/dist/projections/run-dispatch.d.ts +1 -0
- package/dist/projections/run-dispatch.d.ts.map +1 -1
- package/dist/projections/timestamp.d.ts +3 -0
- package/dist/projections/timestamp.d.ts.map +1 -0
- package/dist/projections/types.d.ts +21 -9
- package/dist/projections/types.d.ts.map +1 -1
- package/dist/projections/validation.d.ts +6 -5
- package/dist/projections/validation.d.ts.map +1 -1
- package/dist/query.d.ts +2 -1
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +2 -2
- package/dist/queues/index.d.ts +1 -1
- package/dist/queues/index.d.ts.map +1 -1
- package/dist/queues/types.d.ts +7 -0
- package/dist/queues/types.d.ts.map +1 -1
- package/dist/runtime/ai-cost.d.ts +8 -0
- package/dist/runtime/ai-cost.d.ts.map +1 -0
- package/dist/runtime/create.d.ts +3 -0
- package/dist/runtime/create.d.ts.map +1 -1
- package/dist/runtime/definitions.d.ts +3 -0
- package/dist/runtime/definitions.d.ts.map +1 -1
- package/dist/runtime/host.d.ts +2 -0
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/resolve-definitions.d.ts +2 -0
- package/dist/runtime/resolve-definitions.d.ts.map +1 -1
- package/dist/storage/agents/in-memory.d.ts +22 -4
- package/dist/storage/agents/in-memory.d.ts.map +1 -1
- package/dist/storage/agents/index.d.ts +1 -1
- package/dist/storage/agents/index.d.ts.map +1 -1
- package/dist/storage/agents/provider.d.ts +31 -0
- package/dist/storage/agents/provider.d.ts.map +1 -1
- package/dist/storage/agents/provider.js +22 -7
- package/dist/storage/agents/provider.js.map +1 -1
- package/dist/storage/agents/types.d.ts +75 -4
- package/dist/storage/agents/types.d.ts.map +1 -1
- package/dist/storage/ai-cost/analytics.d.ts +61 -0
- package/dist/storage/ai-cost/analytics.d.ts.map +1 -0
- package/dist/storage/ai-cost/codec.d.ts +14 -0
- package/dist/storage/ai-cost/codec.d.ts.map +1 -0
- package/dist/storage/ai-cost/errors.d.ts +7 -0
- package/dist/storage/ai-cost/errors.d.ts.map +1 -0
- package/dist/storage/ai-cost/in-memory.d.ts +32 -0
- package/dist/storage/ai-cost/in-memory.d.ts.map +1 -0
- package/dist/storage/ai-cost/index.d.ts +6 -0
- package/dist/storage/ai-cost/index.d.ts.map +1 -0
- package/dist/storage/ai-cost/provider.d.ts +7 -0
- package/dist/storage/ai-cost/provider.d.ts.map +1 -0
- package/dist/storage/ai-cost/provider.js +132 -0
- package/dist/storage/ai-cost/provider.js.map +10 -0
- package/dist/storage/ai-cost/types.d.ts +154 -0
- package/dist/storage/ai-cost/types.d.ts.map +1 -0
- package/dist/storage/ai-cost/validation.d.ts +7 -0
- package/dist/storage/ai-cost/validation.d.ts.map +1 -0
- package/dist/storage/ai-usage/in-memory.d.ts +2 -1
- package/dist/storage/ai-usage/in-memory.d.ts.map +1 -1
- package/dist/storage/ai-usage/index.d.ts +1 -1
- package/dist/storage/ai-usage/index.d.ts.map +1 -1
- package/dist/storage/ai-usage/types.d.ts +6 -0
- package/dist/storage/ai-usage/types.d.ts.map +1 -1
- package/dist/storage/in-memory/index.d.ts +5 -0
- package/dist/storage/in-memory/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +6 -3
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +33 -21
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/objects/in-memory.d.ts +6 -3
- package/dist/storage/objects/in-memory.d.ts.map +1 -1
- package/dist/storage/objects/index.d.ts +3 -1
- package/dist/storage/objects/index.d.ts.map +1 -1
- package/dist/storage/objects/keys.d.ts +16 -0
- package/dist/storage/objects/keys.d.ts.map +1 -0
- package/dist/storage/objects/types.d.ts +33 -6
- package/dist/storage/objects/types.d.ts.map +1 -1
- package/dist/storage/ontology/in-memory/materializations.d.ts.map +1 -1
- package/dist/storage/ontology/materializations.d.ts +3 -0
- package/dist/storage/ontology/materializations.d.ts.map +1 -1
- package/dist/storage/ontology/provider.js +1 -1
- package/dist/storage/operation-scope.d.ts.map +1 -1
- package/dist/storage/operation-scope.js +1 -1
- package/dist/storage/types.d.ts +2 -0
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/storage/workflow-runs/provider.js +10 -5
- package/dist/storage/workflow-runs/provider.js.map +1 -1
- package/dist/syncs/index.js +16 -15
- package/dist/syncs/index.js.map +1 -1
- package/dist/testing/agent-storage-contract.d.ts +3 -2
- package/dist/testing/agent-storage-contract.d.ts.map +1 -1
- package/dist/testing/ai-cost-storage-contract.d.ts +12 -0
- package/dist/testing/ai-cost-storage-contract.d.ts.map +1 -0
- package/dist/testing/ai-usage-storage-contract.d.ts.map +1 -1
- package/dist/testing/effective-storage-contract.d.ts +1 -1
- package/dist/testing/effective-storage-contract.d.ts.map +1 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +2525 -1480
- package/dist/testing/index.js.map +10 -9
- package/dist/testing/lake-storage-contract.d.ts.map +1 -1
- package/dist/testing/materializer-storage-contract.d.ts.map +1 -1
- package/dist/testing/object-query-contract.d.ts +1 -1
- package/dist/testing/object-query-contract.d.ts.map +1 -1
- package/dist/webhooks/internal.js +14 -13
- package/dist/webhooks/internal.js.map +2 -2
- package/dist/workers/index.js +12 -2
- package/dist/workers/index.js.map +3 -3
- package/dist/workers/queue-worker.d.ts +2 -0
- package/dist/workers/queue-worker.d.ts.map +1 -1
- package/dist/workflows/execution.d.ts +3 -0
- package/dist/workflows/execution.d.ts.map +1 -1
- package/dist/workflows/index.js +30 -28
- package/dist/workflows/index.js.map +1 -1
- package/package.json +7 -1
- package/src/agents/adapters.ts +64 -23
- package/src/agents/builders.ts +3 -3
- package/src/agents/context-compaction.ts +261 -0
- package/src/agents/errors.ts +2 -2
- package/src/agents/execution.ts +14 -2
- package/src/agents/ids.ts +5 -0
- package/src/agents/index.ts +32 -6
- package/src/agents/request.ts +5 -0
- package/src/agents/streams.ts +56 -0
- package/src/agents/thread-context-projection.ts +93 -0
- package/src/agents/tool-definition.ts +17 -2
- package/src/agents/tool-result.ts +61 -0
- package/src/agents/types.ts +57 -1
- package/src/agents/validation.ts +36 -6
- package/src/http/api-routes.ts +7 -7
- package/src/index.ts +27 -0
- package/src/lake-storage/types.ts +2 -1
- package/src/materialization/model.ts +4 -0
- package/src/materializer/edits/apply.ts +55 -2
- package/src/materializer/edits/operations.ts +8 -1
- package/src/materializer/edits/working-state.ts +7 -0
- package/src/materializer/effective/resolve.ts +78 -9
- package/src/materializer/execution/work-records.ts +3 -1
- package/src/materializer/projections/entry-validator.ts +23 -1
- package/src/materializer/projections/replacement-plan.ts +2 -0
- package/src/materializer/shared/normalize.ts +16 -0
- package/src/materializer/telemetry/append.ts +33 -16
- package/src/models/index.ts +71 -0
- package/src/objects/execution.ts +20 -0
- package/src/objects/link/endpoints.ts +2 -1
- package/src/objects/query/executor.ts +42 -11
- package/src/objects/query/explain.ts +11 -0
- package/src/objects/query/index.ts +6 -0
- package/src/objects/query/ir.ts +16 -0
- package/src/objects/query/links.ts +308 -0
- package/src/objects/query/normalize.ts +40 -1
- package/src/objects/query/planner.ts +5 -0
- package/src/objects/query/validate.ts +58 -2
- package/src/projections/builders.ts +320 -50
- package/src/projections/index.ts +7 -0
- package/src/projections/internal.ts +4 -1
- package/src/projections/ownership.ts +5 -5
- package/src/projections/registry.ts +16 -3
- package/src/projections/revision.ts +35 -5
- package/src/projections/run-dispatch.ts +10 -1
- package/src/projections/timestamp.ts +66 -0
- package/src/projections/types.ts +20 -9
- package/src/projections/validation.ts +85 -19
- package/src/query.ts +2 -0
- package/src/queues/index.ts +1 -0
- package/src/queues/types.ts +8 -0
- package/src/runtime/ai-cost.ts +15 -0
- package/src/runtime/create.ts +4 -0
- package/src/runtime/definitions.ts +3 -0
- package/src/runtime/host.ts +2 -0
- package/src/runtime/resolve-definitions.ts +28 -0
- package/src/storage/agents/in-memory.ts +186 -4
- package/src/storage/agents/index.ts +5 -0
- package/src/storage/agents/provider.ts +225 -0
- package/src/storage/agents/types.ts +82 -3
- package/src/storage/ai-cost/analytics.ts +602 -0
- package/src/storage/ai-cost/codec.ts +136 -0
- package/src/storage/ai-cost/errors.ts +12 -0
- package/src/storage/ai-cost/in-memory.ts +164 -0
- package/src/storage/ai-cost/index.ts +35 -0
- package/src/storage/ai-cost/provider.ts +20 -0
- package/src/storage/ai-cost/types.ts +193 -0
- package/src/storage/ai-cost/validation.ts +337 -0
- package/src/storage/ai-usage/in-memory.ts +23 -0
- package/src/storage/ai-usage/index.ts +1 -0
- package/src/storage/ai-usage/types.ts +10 -0
- package/src/storage/in-memory/index.ts +50 -0
- package/src/storage/index.ts +48 -0
- package/src/storage/objects/in-memory.ts +103 -16
- package/src/storage/objects/index.ts +9 -0
- package/src/storage/objects/keys.ts +36 -0
- package/src/storage/objects/types.ts +34 -6
- package/src/storage/ontology/in-memory/materializations.ts +1 -0
- package/src/storage/ontology/materializations.ts +3 -0
- package/src/storage/ontology/provider-header-validation.ts +2 -2
- package/src/storage/operation-scope.ts +1 -0
- package/src/storage/types.ts +2 -0
- package/src/testing/agent-storage-contract.ts +353 -2
- package/src/testing/ai-cost-storage-contract.ts +320 -0
- package/src/testing/ai-usage-storage-contract.ts +35 -0
- package/src/testing/effective-storage-contract.ts +194 -4
- package/src/testing/index.ts +5 -0
- package/src/testing/lake-storage-contract.ts +56 -0
- package/src/testing/materializer-storage-contract.ts +120 -2
- package/src/testing/object-query-contract.ts +208 -1
- package/src/workers/queue-worker.ts +14 -1
- package/src/workflows/execution.ts +31 -10
- package/dist/agents/prompt.d.ts +0 -15
- package/dist/agents/prompt.d.ts.map +0 -1
- package/dist/chunk-0mbx247x.js.map +0 -43
- package/dist/chunk-34bqh420.js.map +0 -23
- package/dist/chunk-57zpb99z.js.map +0 -10
- package/dist/chunk-663csy96.js.map +0 -10
- package/dist/chunk-6wetht33.js +0 -89
- package/dist/chunk-6wetht33.js.map +0 -10
- package/dist/chunk-88ppkr54.js.map +0 -12
- package/dist/chunk-nnyp53zt.js.map +0 -13
- package/dist/chunk-nten49ta.js.map +0 -12
- package/dist/chunk-st4xgxey.js.map +0 -45
- package/dist/chunk-vp1vc6ee.js +0 -35
- package/dist/chunk-vp1vc6ee.js.map +0 -11
- package/src/agents/prompt.ts +0 -57
- /package/dist/{chunk-sa4340y1.js.map → chunk-1yz3x65y.js.map} +0 -0
- /package/dist/{chunk-gqdd7508.js.map → chunk-4rh2m6zg.js.map} +0 -0
- /package/dist/{chunk-4x43bkbp.js.map → chunk-a09jx26t.js.map} +0 -0
- /package/dist/{chunk-zg9yryhz.js.map → chunk-cbkm2vam.js.map} +0 -0
- /package/dist/{chunk-8ryen3p3.js.map → chunk-f6erf2vv.js.map} +0 -0
- /package/dist/{chunk-bct7hmfc.js.map → chunk-g13869yf.js.map} +0 -0
- /package/dist/{chunk-0k4avqr2.js.map → chunk-hbeh8j9w.js.map} +0 -0
- /package/dist/{chunk-qvybnnpe.js.map → chunk-nzw7sm3b.js.map} +0 -0
- /package/dist/{chunk-bh6k3nc6.js.map → chunk-rs1wbvy6.js.map} +0 -0
- /package/dist/{chunk-7pc8b818.js.map → chunk-sxwk41qa.js.map} +0 -0
- /package/dist/{chunk-5egfka8j.js.map → chunk-tycbzedm.js.map} +0 -0
- /package/dist/{chunk-g9t3kdtx.js.map → chunk-x2yw73hy.js.map} +0 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/projections/timestamp.ts
|
|
3
|
+
var DATASET_TIMESTAMP = /^(\d{4})-(\d{1,2})-(\d{1,2})(?:[ T](\d{1,2}):(\d{2})(?::(\d{2})(?:\.(\d{1,9}))?)?)?([zZ]|[+-]\d{2}:?\d{2})?$/;
|
|
4
|
+
function parseDatasetTimestamp(value) {
|
|
5
|
+
if (value instanceof Date)
|
|
6
|
+
return Number.isNaN(value.getTime()) ? null : value;
|
|
7
|
+
if (typeof value !== "string")
|
|
8
|
+
return null;
|
|
9
|
+
const match = DATASET_TIMESTAMP.exec(value.trim());
|
|
10
|
+
if (!match)
|
|
11
|
+
return null;
|
|
12
|
+
const [, year, month, day, hour, minute, second, fraction, zone] = match;
|
|
13
|
+
const offsetMinutes = parseZoneOffsetMinutes(zone);
|
|
14
|
+
if (offsetMinutes === null)
|
|
15
|
+
return null;
|
|
16
|
+
const components = {
|
|
17
|
+
year: Number(year),
|
|
18
|
+
month: Number(month),
|
|
19
|
+
day: Number(day),
|
|
20
|
+
hour: hour === undefined ? 0 : Number(hour),
|
|
21
|
+
minute: minute === undefined ? 0 : Number(minute),
|
|
22
|
+
second: second === undefined ? 0 : Number(second),
|
|
23
|
+
milliseconds: fraction === undefined ? 0 : Math.trunc(Number(`0.${fraction}`) * 1000)
|
|
24
|
+
};
|
|
25
|
+
const wallClock = Date.UTC(components.year, components.month - 1, components.day, components.hour, components.minute, components.second, components.milliseconds);
|
|
26
|
+
if (!wallClockMatchesComponents(wallClock, components))
|
|
27
|
+
return null;
|
|
28
|
+
return new Date(wallClock - offsetMinutes * 60000);
|
|
29
|
+
}
|
|
30
|
+
function parseZoneOffsetMinutes(zone) {
|
|
31
|
+
if (zone === undefined || zone === "Z" || zone === "z")
|
|
32
|
+
return 0;
|
|
33
|
+
const digits = zone.slice(1).replace(":", "");
|
|
34
|
+
const hours = Number(digits.slice(0, 2));
|
|
35
|
+
const minutes = Number(digits.slice(2, 4));
|
|
36
|
+
if (hours > 23 || minutes > 59)
|
|
37
|
+
return null;
|
|
38
|
+
return (zone[0] === "-" ? -1 : 1) * (hours * 60 + minutes);
|
|
39
|
+
}
|
|
40
|
+
function wallClockMatchesComponents(wallClock, components) {
|
|
41
|
+
const date = new Date(wallClock);
|
|
42
|
+
return date.getUTCFullYear() === components.year && date.getUTCMonth() === components.month - 1 && date.getUTCDate() === components.day && date.getUTCHours() === components.hour && date.getUTCMinutes() === components.minute && date.getUTCSeconds() === components.second;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { parseDatasetTimestamp };
|
|
46
|
+
|
|
47
|
+
//# debugId=E9A28815FA1B574C64756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/projections/timestamp.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"const DATASET_TIMESTAMP =\n /^(\\d{4})-(\\d{1,2})-(\\d{1,2})(?:[ T](\\d{1,2}):(\\d{2})(?::(\\d{2})(?:\\.(\\d{1,9}))?)?)?([zZ]|[+-]\\d{2}:?\\d{2})?$/\n\ninterface TimestampComponents {\n readonly year: number\n readonly month: number\n readonly day: number\n readonly hour: number\n readonly minute: number\n readonly second: number\n readonly milliseconds: number\n}\n\n/** Parses a projection dataset timestamp, interpreting zone-less values as UTC. */\nexport function parseDatasetTimestamp(value: unknown): Date | null {\n if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value\n if (typeof value !== \"string\") return null\n\n const match = DATASET_TIMESTAMP.exec(value.trim())\n if (!match) return null\n const [, year, month, day, hour, minute, second, fraction, zone] = match\n const offsetMinutes = parseZoneOffsetMinutes(zone)\n if (offsetMinutes === null) return null\n\n const components: TimestampComponents = {\n year: Number(year),\n month: Number(month),\n day: Number(day),\n hour: hour === undefined ? 0 : Number(hour),\n minute: minute === undefined ? 0 : Number(minute),\n second: second === undefined ? 0 : Number(second),\n milliseconds: fraction === undefined ? 0 : Math.trunc(Number(`0.${fraction}`) * 1000),\n }\n const wallClock = Date.UTC(\n components.year,\n components.month - 1,\n components.day,\n components.hour,\n components.minute,\n components.second,\n components.milliseconds\n )\n if (!wallClockMatchesComponents(wallClock, components)) return null\n return new Date(wallClock - offsetMinutes * 60_000)\n}\n\nfunction parseZoneOffsetMinutes(zone: string | undefined): number | null {\n if (zone === undefined || zone === \"Z\" || zone === \"z\") return 0\n const digits = zone.slice(1).replace(\":\", \"\")\n const hours = Number(digits.slice(0, 2))\n const minutes = Number(digits.slice(2, 4))\n if (hours > 23 || minutes > 59) return null\n return (zone[0] === \"-\" ? -1 : 1) * (hours * 60 + minutes)\n}\n\nfunction wallClockMatchesComponents(wallClock: number, components: TimestampComponents): boolean {\n const date = new Date(wallClock)\n return (\n date.getUTCFullYear() === components.year &&\n date.getUTCMonth() === components.month - 1 &&\n date.getUTCDate() === components.day &&\n date.getUTCHours() === components.hour &&\n date.getUTCMinutes() === components.minute &&\n date.getUTCSeconds() === components.second\n )\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";;AAAA,IAAM,oBACJ;AAaK,SAAS,qBAAqB,CAAC,OAA6B;AAAA,EACjE,IAAI,iBAAiB;AAAA,IAAM,OAAO,OAAO,MAAM,MAAM,QAAQ,CAAC,IAAI,OAAO;AAAA,EACzE,IAAI,OAAO,UAAU;AAAA,IAAU,OAAO;AAAA,EAEtC,MAAM,QAAQ,kBAAkB,KAAK,MAAM,KAAK,CAAC;AAAA,EACjD,IAAI,CAAC;AAAA,IAAO,OAAO;AAAA,EACnB,SAAS,MAAM,OAAO,KAAK,MAAM,QAAQ,QAAQ,UAAU,QAAQ;AAAA,EACnE,MAAM,gBAAgB,uBAAuB,IAAI;AAAA,EACjD,IAAI,kBAAkB;AAAA,IAAM,OAAO;AAAA,EAEnC,MAAM,aAAkC;AAAA,IACtC,MAAM,OAAO,IAAI;AAAA,IACjB,OAAO,OAAO,KAAK;AAAA,IACnB,KAAK,OAAO,GAAG;AAAA,IACf,MAAM,SAAS,YAAY,IAAI,OAAO,IAAI;AAAA,IAC1C,QAAQ,WAAW,YAAY,IAAI,OAAO,MAAM;AAAA,IAChD,QAAQ,WAAW,YAAY,IAAI,OAAO,MAAM;AAAA,IAChD,cAAc,aAAa,YAAY,IAAI,KAAK,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,EACtF;AAAA,EACA,MAAM,YAAY,KAAK,IACrB,WAAW,MACX,WAAW,QAAQ,GACnB,WAAW,KACX,WAAW,MACX,WAAW,QACX,WAAW,QACX,WAAW,YACb;AAAA,EACA,IAAI,CAAC,2BAA2B,WAAW,UAAU;AAAA,IAAG,OAAO;AAAA,EAC/D,OAAO,IAAI,KAAK,YAAY,gBAAgB,KAAM;AAAA;AAGpD,SAAS,sBAAsB,CAAC,MAAyC;AAAA,EACvE,IAAI,SAAS,aAAa,SAAS,OAAO,SAAS;AAAA,IAAK,OAAO;AAAA,EAC/D,MAAM,SAAS,KAAK,MAAM,CAAC,EAAE,QAAQ,KAAK,EAAE;AAAA,EAC5C,MAAM,QAAQ,OAAO,OAAO,MAAM,GAAG,CAAC,CAAC;AAAA,EACvC,MAAM,UAAU,OAAO,OAAO,MAAM,GAAG,CAAC,CAAC;AAAA,EACzC,IAAI,QAAQ,MAAM,UAAU;AAAA,IAAI,OAAO;AAAA,EACvC,QAAQ,KAAK,OAAO,MAAM,KAAK,MAAM,QAAQ,KAAK;AAAA;AAGpD,SAAS,0BAA0B,CAAC,WAAmB,YAA0C;AAAA,EAC/F,MAAM,OAAO,IAAI,KAAK,SAAS;AAAA,EAC/B,OACE,KAAK,eAAe,MAAM,WAAW,QACrC,KAAK,YAAY,MAAM,WAAW,QAAQ,KAC1C,KAAK,WAAW,MAAM,WAAW,OACjC,KAAK,YAAY,MAAM,WAAW,QAClC,KAAK,cAAc,MAAM,WAAW,UACpC,KAAK,cAAc,MAAM,WAAW;AAAA;",
|
|
8
|
+
"debugId": "E9A28815FA1B574C64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
import {
|
|
3
|
+
parseDatasetTimestamp
|
|
4
|
+
} from "./chunk-96swp2wd.js";
|
|
2
5
|
import {
|
|
3
6
|
ensureExecutionRecord,
|
|
4
7
|
executionRecordInputFromRuntime
|
|
5
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-f6erf2vv.js";
|
|
6
9
|
import {
|
|
7
10
|
isStorageSerializationFailure
|
|
8
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-1wk20wn3.js";
|
|
9
12
|
import {
|
|
10
13
|
createCommitId,
|
|
11
14
|
createEventId,
|
|
@@ -13,7 +16,7 @@ import {
|
|
|
13
16
|
materializationApplyPhase,
|
|
14
17
|
materializationEventKindOrdinal,
|
|
15
18
|
sha256Canonical
|
|
16
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-72q2y8hn.js";
|
|
17
20
|
import {
|
|
18
21
|
assertPinnedDatasetWatermark
|
|
19
22
|
} from "./chunk-9dzba0f2.js";
|
|
@@ -41,6 +44,12 @@ import {
|
|
|
41
44
|
MaterializationObjectNotFoundError,
|
|
42
45
|
MaterializationValidationError
|
|
43
46
|
} from "./chunk-ry24jbr1.js";
|
|
47
|
+
import {
|
|
48
|
+
ProjectionValidationError,
|
|
49
|
+
isProjectionDefinition,
|
|
50
|
+
resolveExecutionScopeAuthorization,
|
|
51
|
+
validateProjectionsAtStartup
|
|
52
|
+
} from "./chunk-f83ka50g.js";
|
|
44
53
|
import {
|
|
45
54
|
assertKnownProperties,
|
|
46
55
|
normalizeLinkProperties,
|
|
@@ -51,12 +60,6 @@ import {
|
|
|
51
60
|
validatePropertyValue,
|
|
52
61
|
validateTelemetryUnit
|
|
53
62
|
} from "./chunk-rnshztfq.js";
|
|
54
|
-
import {
|
|
55
|
-
ProjectionValidationError,
|
|
56
|
-
isProjectionDefinition,
|
|
57
|
-
resolveExecutionScopeAuthorization,
|
|
58
|
-
validateProjectionsAtStartup
|
|
59
|
-
} from "./chunk-34bqh420.js";
|
|
60
63
|
import {
|
|
61
64
|
assertJsonValue,
|
|
62
65
|
cloneJsonValue,
|
|
@@ -169,7 +172,8 @@ function normalizeProjectionDefinition(projection) {
|
|
|
169
172
|
sourceField: link.sourceField ?? null,
|
|
170
173
|
targetObjectTypeId: link.targetObjectTypeId
|
|
171
174
|
}
|
|
172
|
-
]))
|
|
175
|
+
])),
|
|
176
|
+
conflictResolution: projection.conflictResolution ?? { strategy: "editsWin" }
|
|
173
177
|
};
|
|
174
178
|
}
|
|
175
179
|
if (projection._tag === "LinkProjectionDefinition") {
|
|
@@ -182,21 +186,39 @@ function normalizeProjectionDefinition(projection) {
|
|
|
182
186
|
targetField: projection.targetField
|
|
183
187
|
};
|
|
184
188
|
}
|
|
189
|
+
const properties = Object.entries(projection.properties).sort(([left], [right]) => compareStrings(left, right));
|
|
190
|
+
if (properties.length === 1) {
|
|
191
|
+
const [propertyId, mapping] = properties[0];
|
|
192
|
+
return {
|
|
193
|
+
kind: "telemetry",
|
|
194
|
+
objectTypeId: projection.objectTypeId,
|
|
195
|
+
propertyId,
|
|
196
|
+
objectIdField: projection.objectIdField,
|
|
197
|
+
atField: projection.atField,
|
|
198
|
+
valueField: mapping.valueField,
|
|
199
|
+
unitField: mapping.unitField ?? null
|
|
200
|
+
};
|
|
201
|
+
}
|
|
185
202
|
return {
|
|
186
203
|
kind: "telemetry",
|
|
187
204
|
objectTypeId: projection.objectTypeId,
|
|
188
|
-
propertyId: projection.propertyId,
|
|
189
205
|
objectIdField: projection.objectIdField,
|
|
190
206
|
atField: projection.atField,
|
|
191
|
-
|
|
192
|
-
|
|
207
|
+
properties: Object.fromEntries(properties.map(([propertyId, mapping]) => [
|
|
208
|
+
propertyId,
|
|
209
|
+
{
|
|
210
|
+
valueField: mapping.valueField,
|
|
211
|
+
unitField: mapping.unitField ?? null
|
|
212
|
+
}
|
|
213
|
+
]))
|
|
193
214
|
};
|
|
194
215
|
}
|
|
195
216
|
function projectionColumns(projection) {
|
|
196
217
|
if (projection._tag === "ObjectProjectionDefinition") {
|
|
197
218
|
return new Set([
|
|
198
219
|
...Object.values(projection.properties),
|
|
199
|
-
...Object.values(projection.links).flatMap((link) => link.sourceField === undefined ? [] : [link.sourceField])
|
|
220
|
+
...Object.values(projection.links).flatMap((link) => link.sourceField === undefined ? [] : [link.sourceField]),
|
|
221
|
+
...projection.conflictResolution?.strategy === "mostRecent" ? [projection.conflictResolution.sourceTimestamp] : []
|
|
200
222
|
]);
|
|
201
223
|
}
|
|
202
224
|
if (projection._tag === "LinkProjectionDefinition") {
|
|
@@ -205,8 +227,10 @@ function projectionColumns(projection) {
|
|
|
205
227
|
return new Set([
|
|
206
228
|
projection.objectIdField,
|
|
207
229
|
projection.atField,
|
|
208
|
-
projection.
|
|
209
|
-
|
|
230
|
+
...Object.values(projection.properties).flatMap((mapping) => [
|
|
231
|
+
mapping.valueField,
|
|
232
|
+
...mapping.unitField === undefined ? [] : [mapping.unitField]
|
|
233
|
+
])
|
|
210
234
|
]);
|
|
211
235
|
}
|
|
212
236
|
function normalizeProperty(property) {
|
|
@@ -424,7 +448,11 @@ function cloneObjectProjectionDefinition(projection) {
|
|
|
424
448
|
...descriptor.sourceField !== undefined ? { sourceField: descriptor.sourceField } : {},
|
|
425
449
|
targetObjectTypeId: descriptor.targetObjectTypeId
|
|
426
450
|
}
|
|
427
|
-
]))
|
|
451
|
+
])),
|
|
452
|
+
conflictResolution: projection.conflictResolution?.strategy === "mostRecent" ? {
|
|
453
|
+
strategy: "mostRecent",
|
|
454
|
+
sourceTimestamp: projection.conflictResolution.sourceTimestamp
|
|
455
|
+
} : { strategy: "editsWin" }
|
|
428
456
|
};
|
|
429
457
|
}
|
|
430
458
|
function cloneLinkProjectionDefinition(projection) {
|
|
@@ -444,12 +472,16 @@ function cloneTelemetryProjectionDefinition(projection) {
|
|
|
444
472
|
_tag: "TelemetryProjectionDefinition",
|
|
445
473
|
id: projection.id,
|
|
446
474
|
objectTypeId: projection.objectTypeId,
|
|
447
|
-
propertyId: projection.propertyId,
|
|
448
475
|
datasetId: projection.datasetId,
|
|
449
476
|
objectIdField: projection.objectIdField,
|
|
450
477
|
atField: projection.atField,
|
|
451
|
-
|
|
452
|
-
|
|
478
|
+
properties: Object.fromEntries(Object.entries(projection.properties).map(([propertyId, mapping]) => [
|
|
479
|
+
propertyId,
|
|
480
|
+
{
|
|
481
|
+
valueField: mapping.valueField,
|
|
482
|
+
...mapping.unitField !== undefined ? { unitField: mapping.unitField } : {}
|
|
483
|
+
}
|
|
484
|
+
]))
|
|
453
485
|
};
|
|
454
486
|
}
|
|
455
487
|
function deepFreeze(value) {
|
|
@@ -882,7 +914,7 @@ function appendItem(chunk, item) {
|
|
|
882
914
|
|
|
883
915
|
// src/materializer/execution/work-records.ts
|
|
884
916
|
function appendObjectOverrideWork(items, working, identity) {
|
|
885
|
-
if (stableJsonStringify(working.originalOverride?.value ?? null) === stableJsonStringify(working.override)) {
|
|
917
|
+
if (stableJsonStringify(working.originalOverride?.value ?? null) === stableJsonStringify(working.override) && stableJsonStringify(working.originalEditedAt) === stableJsonStringify(working.editedAt)) {
|
|
886
918
|
return;
|
|
887
919
|
}
|
|
888
920
|
if (working.override) {
|
|
@@ -891,6 +923,7 @@ function appendObjectOverrideWork(items, working, identity) {
|
|
|
891
923
|
value: {
|
|
892
924
|
ref: working.ref,
|
|
893
925
|
value: working.override,
|
|
926
|
+
editedAt: working.editedAt,
|
|
894
927
|
expectedLastCommitId: working.originalOverride?.lastCommitId ?? null,
|
|
895
928
|
lastCommitId: identity.commitId,
|
|
896
929
|
updatedAt: identity.committedAt
|
|
@@ -1160,6 +1193,13 @@ function normalizeTimestamp(value, label) {
|
|
|
1160
1193
|
}
|
|
1161
1194
|
return new Date(milliseconds).toISOString();
|
|
1162
1195
|
}
|
|
1196
|
+
function normalizeProjectionSourceTimestamp(value) {
|
|
1197
|
+
const timestamp = parseDatasetTimestamp(value);
|
|
1198
|
+
if (!timestamp) {
|
|
1199
|
+
throw new MaterializationValidationError("Projection source update timestamp must be a valid timestamp.");
|
|
1200
|
+
}
|
|
1201
|
+
return timestamp.toISOString();
|
|
1202
|
+
}
|
|
1163
1203
|
function normalizePropertyIds(values, label) {
|
|
1164
1204
|
const seen = new Set;
|
|
1165
1205
|
const normalized = [];
|
|
@@ -1369,7 +1409,10 @@ function normalizeProjectionAssertion(assertion) {
|
|
|
1369
1409
|
return assertion.kind === "object" ? Object.freeze({
|
|
1370
1410
|
kind: "object",
|
|
1371
1411
|
ref: normalizeObjectRef(assertion.ref),
|
|
1372
|
-
properties: normalizeJsonProperties(assertion.properties)
|
|
1412
|
+
properties: normalizeJsonProperties(assertion.properties),
|
|
1413
|
+
...assertion.sourceUpdatedAt !== undefined ? {
|
|
1414
|
+
sourceUpdatedAt: normalizeProjectionSourceTimestamp(assertion.sourceUpdatedAt)
|
|
1415
|
+
} : {}
|
|
1373
1416
|
}) : Object.freeze({
|
|
1374
1417
|
kind: "link",
|
|
1375
1418
|
ref: normalizeLinkRef(assertion.ref),
|
|
@@ -1526,35 +1569,76 @@ function usableLinkSlotOverride(stored) {
|
|
|
1526
1569
|
throw new MaterializationConflictError("effective-state", `Cardinality-one link slot ${scopeLabel} could not be migrated automatically because it ` + "contains multiple legacy upsert overrides. Consolidate the stored overrides and clear " + "the migration conflict marker before materializing this scope.");
|
|
1527
1570
|
}
|
|
1528
1571
|
function resolveEffectiveObject(input) {
|
|
1529
|
-
const properties = resolveObjectAuthority(input.source, input.override);
|
|
1572
|
+
const properties = resolveObjectAuthority(input.source, input.override, input.editedAt);
|
|
1530
1573
|
if (!properties)
|
|
1531
1574
|
return null;
|
|
1532
1575
|
properties[input.primaryPropertyId] = input.ref.primaryId;
|
|
1533
1576
|
applyLatestTelemetry(properties, input.latestTelemetry);
|
|
1534
1577
|
return { ref: input.ref, properties };
|
|
1535
1578
|
}
|
|
1536
|
-
function resolveObjectAuthority(source, override) {
|
|
1579
|
+
function resolveObjectAuthority(source, override, editedAt) {
|
|
1537
1580
|
switch (override?.kind) {
|
|
1538
1581
|
case "delete":
|
|
1539
1582
|
return null;
|
|
1540
1583
|
case "create":
|
|
1541
|
-
|
|
1584
|
+
if (!source)
|
|
1585
|
+
return { ...override.properties };
|
|
1586
|
+
return resolveSourceAndEdits(source, override, editedAt);
|
|
1542
1587
|
case "patch":
|
|
1543
1588
|
if (!source)
|
|
1544
1589
|
return null;
|
|
1545
|
-
return
|
|
1590
|
+
return resolveSourceAndEdits(source, override, editedAt);
|
|
1546
1591
|
default:
|
|
1547
1592
|
if (!source)
|
|
1548
1593
|
return null;
|
|
1549
1594
|
return { ...source.assertion.properties };
|
|
1550
1595
|
}
|
|
1551
1596
|
}
|
|
1552
|
-
function
|
|
1553
|
-
const properties = { ...
|
|
1554
|
-
|
|
1555
|
-
|
|
1597
|
+
function resolveSourceAndEdits(source, override, editedAt) {
|
|
1598
|
+
const properties = { ...source.assertion.properties };
|
|
1599
|
+
const absentSourcePropertyIds = new Set(source.assertion.absentSourcePropertyIds ?? []);
|
|
1600
|
+
for (const propertyId of objectEditCandidateIds(override, editedAt)) {
|
|
1601
|
+
const edit = objectEditCandidate(override, propertyId);
|
|
1602
|
+
const editTimestamp = editedAt[propertyId];
|
|
1603
|
+
const hasSourceCandidate = Object.hasOwn(source.assertion.properties, propertyId) || absentSourcePropertyIds.has(propertyId);
|
|
1604
|
+
const sourceWins = hasSourceCandidate && source.assertion.sourceUpdatedAt !== undefined && editTimestamp !== undefined && source.assertion.sourceUpdatedAt.localeCompare(editTimestamp) >= 0;
|
|
1605
|
+
if (!sourceWins)
|
|
1606
|
+
applyObjectEditCandidate(properties, propertyId, edit);
|
|
1607
|
+
}
|
|
1556
1608
|
return properties;
|
|
1557
1609
|
}
|
|
1610
|
+
function objectEditCandidateIds(override, editedAt) {
|
|
1611
|
+
const ids = new Set(Object.keys(editedAt));
|
|
1612
|
+
if (override.kind === "create") {
|
|
1613
|
+
for (const propertyId of Object.keys(override.properties))
|
|
1614
|
+
ids.add(propertyId);
|
|
1615
|
+
} else {
|
|
1616
|
+
for (const propertyId of Object.keys(override.set))
|
|
1617
|
+
ids.add(propertyId);
|
|
1618
|
+
for (const propertyId of override.unset)
|
|
1619
|
+
ids.add(propertyId);
|
|
1620
|
+
}
|
|
1621
|
+
return [...ids];
|
|
1622
|
+
}
|
|
1623
|
+
function objectEditCandidate(override, propertyId) {
|
|
1624
|
+
const values = override.kind === "create" ? override.properties : override.set;
|
|
1625
|
+
return Object.hasOwn(values, propertyId) ? { present: true, value: values[propertyId] } : { present: false };
|
|
1626
|
+
}
|
|
1627
|
+
function applyObjectEditCandidate(properties, propertyId, candidate) {
|
|
1628
|
+
if (candidate.present)
|
|
1629
|
+
properties[propertyId] = candidate.value;
|
|
1630
|
+
else
|
|
1631
|
+
delete properties[propertyId];
|
|
1632
|
+
}
|
|
1633
|
+
function storedObjectEditedAt(stored) {
|
|
1634
|
+
if (!stored || stored.value.kind === "delete")
|
|
1635
|
+
return {};
|
|
1636
|
+
const editedAt = { ...stored.editedAt ?? {} };
|
|
1637
|
+
const candidateIds = stored.value.kind === "create" ? Object.keys(stored.value.properties) : [...Object.keys(stored.value.set), ...stored.value.unset];
|
|
1638
|
+
for (const propertyId of candidateIds)
|
|
1639
|
+
editedAt[propertyId] ??= stored.updatedAt;
|
|
1640
|
+
return editedAt;
|
|
1641
|
+
}
|
|
1558
1642
|
function applyLatestTelemetry(properties, latestTelemetry) {
|
|
1559
1643
|
for (const point of latestTelemetry)
|
|
1560
1644
|
properties[point.series.propertyId] = point.value;
|
|
@@ -1683,11 +1767,14 @@ function workingLinkSlotFromState(scope) {
|
|
|
1683
1767
|
};
|
|
1684
1768
|
}
|
|
1685
1769
|
function workingObjectFromState(object) {
|
|
1770
|
+
const editedAt = storedObjectEditedAt(object.override);
|
|
1686
1771
|
return {
|
|
1687
1772
|
ref: object.ref,
|
|
1688
1773
|
source: object.source,
|
|
1689
1774
|
originalOverride: object.override,
|
|
1690
1775
|
override: object.override?.value ?? null,
|
|
1776
|
+
originalEditedAt: editedAt,
|
|
1777
|
+
editedAt: { ...editedAt },
|
|
1691
1778
|
before: object.effective,
|
|
1692
1779
|
latestTelemetry: [...object.latestTelemetry]
|
|
1693
1780
|
};
|
|
@@ -1707,6 +1794,7 @@ function resolveObject(ontology, working) {
|
|
|
1707
1794
|
primaryPropertyId: ontology.getPrimaryPropertyId(working.ref.objectTypeId),
|
|
1708
1795
|
source: working.source,
|
|
1709
1796
|
override: working.override,
|
|
1797
|
+
editedAt: working.editedAt,
|
|
1710
1798
|
latestTelemetry: working.latestTelemetry
|
|
1711
1799
|
});
|
|
1712
1800
|
}
|
|
@@ -2136,7 +2224,7 @@ function applyObjectEdit(input) {
|
|
|
2136
2224
|
next = applyObjectUpsert(input, input.operation);
|
|
2137
2225
|
break;
|
|
2138
2226
|
case "object.patch":
|
|
2139
|
-
next =
|
|
2227
|
+
next = applyObjectPatch(input, input.operation);
|
|
2140
2228
|
break;
|
|
2141
2229
|
case "object.delete":
|
|
2142
2230
|
next = applyObjectDelete(input);
|
|
@@ -2147,7 +2235,47 @@ function applyObjectEdit(input) {
|
|
|
2147
2235
|
default:
|
|
2148
2236
|
throw new MaterializationValidationError("Expected an object edit operation.");
|
|
2149
2237
|
}
|
|
2150
|
-
|
|
2238
|
+
const editedAt = applyObjectEditTimes(input, next);
|
|
2239
|
+
const authority = transition(current, next);
|
|
2240
|
+
return {
|
|
2241
|
+
...authority,
|
|
2242
|
+
editedAt,
|
|
2243
|
+
changed: authority.changed || !sameStringRecord(input.editedAt, editedAt)
|
|
2244
|
+
};
|
|
2245
|
+
}
|
|
2246
|
+
function applyObjectEditTimes(input, next) {
|
|
2247
|
+
if (!next || next.kind === "delete")
|
|
2248
|
+
return {};
|
|
2249
|
+
const editedAt = input.operation.kind === "object.create" || input.authority?.kind === "delete" ? {} : { ...input.editedAt };
|
|
2250
|
+
switch (input.operation.kind) {
|
|
2251
|
+
case "object.create":
|
|
2252
|
+
case "object.upsert": {
|
|
2253
|
+
const properties = input.normalizedProperties ?? input.operation.properties;
|
|
2254
|
+
for (const propertyId of Object.keys(properties))
|
|
2255
|
+
editedAt[propertyId] = input.committedAt;
|
|
2256
|
+
break;
|
|
2257
|
+
}
|
|
2258
|
+
case "object.patch":
|
|
2259
|
+
for (const propertyId of input.operation.reset)
|
|
2260
|
+
delete editedAt[propertyId];
|
|
2261
|
+
for (const propertyId of input.operation.unset)
|
|
2262
|
+
editedAt[propertyId] = input.committedAt;
|
|
2263
|
+
for (const propertyId of Object.keys(input.normalizedSet ?? input.operation.set)) {
|
|
2264
|
+
editedAt[propertyId] = input.committedAt;
|
|
2265
|
+
}
|
|
2266
|
+
break;
|
|
2267
|
+
case "object.delete":
|
|
2268
|
+
return editedAt;
|
|
2269
|
+
case "object.restore":
|
|
2270
|
+
break;
|
|
2271
|
+
}
|
|
2272
|
+
return editedAt;
|
|
2273
|
+
}
|
|
2274
|
+
function sameStringRecord(left, right) {
|
|
2275
|
+
const leftKeys = Object.keys(left);
|
|
2276
|
+
if (leftKeys.length !== Object.keys(right).length)
|
|
2277
|
+
return false;
|
|
2278
|
+
return leftKeys.every((key) => left[key] === right[key]);
|
|
2151
2279
|
}
|
|
2152
2280
|
function applyObjectCreate(input, operation) {
|
|
2153
2281
|
if (input.sourceProperties || input.authority) {
|
|
@@ -2178,7 +2306,7 @@ function mergeUpsertIntoPatch(current, properties, hasSource) {
|
|
|
2178
2306
|
delete created[propertyId];
|
|
2179
2307
|
return { kind: "create", properties: { ...created, ...properties } };
|
|
2180
2308
|
}
|
|
2181
|
-
function
|
|
2309
|
+
function applyObjectPatch(input, operation) {
|
|
2182
2310
|
const current = input.authority;
|
|
2183
2311
|
if (!input.effectiveExists && current?.kind !== "patch") {
|
|
2184
2312
|
throw new MaterializationValidationError(`Object patch requires an effective object for ${operation.ref.objectTypeId}:${operation.ref.primaryId}.`);
|
|
@@ -2304,10 +2432,12 @@ function applyObjectOperation(context, state, operation, identity, journal) {
|
|
|
2304
2432
|
operation,
|
|
2305
2433
|
sourceProperties: working.source?.assertion.properties ?? null,
|
|
2306
2434
|
authority: working.override,
|
|
2435
|
+
editedAt: working.editedAt,
|
|
2436
|
+
committedAt: identity.committedAt,
|
|
2307
2437
|
effectiveExists: currentEffective !== null,
|
|
2308
2438
|
...normalized
|
|
2309
2439
|
});
|
|
2310
|
-
applyObjectTransition(context, state, working, transition2.next, journal);
|
|
2440
|
+
applyObjectTransition(context, state, working, transition2.next, transition2.editedAt, journal);
|
|
2311
2441
|
return objectOperationOutcome(operation, working, transition2.changed, context, identity);
|
|
2312
2442
|
}
|
|
2313
2443
|
function requireWorkingObject(state, operation) {
|
|
@@ -2334,9 +2464,11 @@ function validateObjectOperation(context, operation) {
|
|
|
2334
2464
|
return {};
|
|
2335
2465
|
}
|
|
2336
2466
|
}
|
|
2337
|
-
function applyObjectTransition(context, state, working, next, journal) {
|
|
2467
|
+
function applyObjectTransition(context, state, working, next, nextEditedAt, journal) {
|
|
2338
2468
|
const previous = working.override;
|
|
2469
|
+
const previousEditedAt = working.editedAt;
|
|
2339
2470
|
working.override = next;
|
|
2471
|
+
working.editedAt = { ...nextEditedAt };
|
|
2340
2472
|
try {
|
|
2341
2473
|
const resolved = resolveObject(context.ontology, working);
|
|
2342
2474
|
if (resolved)
|
|
@@ -2344,11 +2476,13 @@ function applyObjectTransition(context, state, working, next, journal) {
|
|
|
2344
2476
|
validateWorkingCardinality(state.links.slots);
|
|
2345
2477
|
} catch (error) {
|
|
2346
2478
|
working.override = previous;
|
|
2479
|
+
working.editedAt = previousEditedAt;
|
|
2347
2480
|
throw error;
|
|
2348
2481
|
}
|
|
2349
2482
|
journal?.push({
|
|
2350
2483
|
restore: () => {
|
|
2351
2484
|
working.override = previous;
|
|
2485
|
+
working.editedAt = previousEditedAt;
|
|
2352
2486
|
}
|
|
2353
2487
|
});
|
|
2354
2488
|
}
|
|
@@ -3035,7 +3169,22 @@ function validateObjectAssertion(ontology, resolved, policy, assertion) {
|
|
|
3035
3169
|
continue;
|
|
3036
3170
|
throw new MaterializationValidationError(`Projection '${resolved.projectionId}' asserted unowned property '${assertion.ref.objectTypeId}.${propertyId}'.`);
|
|
3037
3171
|
}
|
|
3038
|
-
|
|
3172
|
+
const conflictResolution = resolved.definition.conflictResolution ?? { strategy: "editsWin" };
|
|
3173
|
+
if (conflictResolution.strategy !== "mostRecent") {
|
|
3174
|
+
return { kind: "object", ref: assertion.ref, properties };
|
|
3175
|
+
}
|
|
3176
|
+
if (assertion.sourceUpdatedAt === undefined) {
|
|
3177
|
+
throw new MaterializationValidationError(`Projection '${resolved.projectionId}' requires source update timestamp ` + `'${conflictResolution.sourceTimestamp}' on every object assertion.`);
|
|
3178
|
+
}
|
|
3179
|
+
const primaryPropertyId = ontology.getPrimaryPropertyId(assertion.ref.objectTypeId);
|
|
3180
|
+
const absentSourcePropertyIds = [...owned].filter((propertyId) => propertyId !== primaryPropertyId && !Object.hasOwn(properties, propertyId)).sort();
|
|
3181
|
+
return {
|
|
3182
|
+
kind: "object",
|
|
3183
|
+
ref: assertion.ref,
|
|
3184
|
+
properties,
|
|
3185
|
+
sourceUpdatedAt: assertion.sourceUpdatedAt,
|
|
3186
|
+
...absentSourcePropertyIds.length === 0 ? {} : { absentSourcePropertyIds }
|
|
3187
|
+
};
|
|
3039
3188
|
}
|
|
3040
3189
|
function validateLinkAssertion(ontology, resolved, policy, assertion) {
|
|
3041
3190
|
const ownershipKey = linkOwnershipKey(assertion.ref.source.objectTypeId, assertion.ref.linkId);
|
|
@@ -3283,6 +3432,7 @@ function resolveReplacementObject(context, state) {
|
|
|
3283
3432
|
primaryPropertyId: context.ontology.getPrimaryPropertyId(state.ref.objectTypeId),
|
|
3284
3433
|
source: state.candidateSource,
|
|
3285
3434
|
override: state.override?.value ?? null,
|
|
3435
|
+
editedAt: storedObjectEditedAt(state.override),
|
|
3286
3436
|
latestTelemetry: state.latestTelemetry
|
|
3287
3437
|
});
|
|
3288
3438
|
}
|
|
@@ -3845,7 +3995,6 @@ function prepareTelemetryAppend(context, raw) {
|
|
|
3845
3995
|
points: raw.input.points.map((point) => validateTelemetryPoint(context.ontology, point))
|
|
3846
3996
|
});
|
|
3847
3997
|
const inputPointCount = telemetryInputPointCount(input, rawInputPointCount);
|
|
3848
|
-
validateTelemetryBatch(input, inputPointCount);
|
|
3849
3998
|
const ontologyRevision = context.projectionRegistry.ontologyRevision;
|
|
3850
3999
|
const execution = prepareMaterializerExecution(context.projectId, raw.scope);
|
|
3851
4000
|
if (input.source.kind === "runtime") {
|
|
@@ -3864,16 +4013,6 @@ function telemetryInputPointCount(input, rawInputPointCount) {
|
|
|
3864
4013
|
return rawInputPointCount;
|
|
3865
4014
|
return input.points.length;
|
|
3866
4015
|
}
|
|
3867
|
-
function validateTelemetryBatch(input, inputPointCount) {
|
|
3868
|
-
if (input.source.kind === "projection") {
|
|
3869
|
-
if (input.source.sourceRowCount === 0) {
|
|
3870
|
-
throw new MaterializationValidationError("Projection telemetry batches must consume at least one source row; an empty dataset produces no batch commit.");
|
|
3871
|
-
}
|
|
3872
|
-
if (input.source.sourceRowCount !== inputPointCount + input.source.sourceRowsSkipped) {
|
|
3873
|
-
throw new MaterializationValidationError("Projection telemetry sourceRowCount must equal input points plus skipped rows.");
|
|
3874
|
-
}
|
|
3875
|
-
}
|
|
3876
|
-
}
|
|
3877
4016
|
function prepareRuntimeTelemetry(context, input, source, inputPointCount, ontologyRevision) {
|
|
3878
4017
|
const identity = createTimedCommitIdentity({
|
|
3879
4018
|
projectId: context.projectId,
|
|
@@ -3887,6 +4026,7 @@ function prepareProjectionTelemetry(context, input, source, inputPointCount, ont
|
|
|
3887
4026
|
const resolvedProjection = context.projectionRegistry.resolveTelemetry(source.projection.projectionId);
|
|
3888
4027
|
validateTelemetryProjectionDataset(resolvedProjection, source);
|
|
3889
4028
|
validateTelemetryOwnership(resolvedProjection, input);
|
|
4029
|
+
validateTelemetryBatchCardinality(resolvedProjection, source, inputPointCount);
|
|
3890
4030
|
const runIdentity = createProjectionRunMaterializationIdentity({
|
|
3891
4031
|
resolved: resolvedProjection,
|
|
3892
4032
|
datasetVersion: source.datasetVersion,
|
|
@@ -3909,6 +4049,23 @@ function prepareProjectionTelemetry(context, input, source, inputPointCount, ont
|
|
|
3909
4049
|
runIdentity
|
|
3910
4050
|
};
|
|
3911
4051
|
}
|
|
4052
|
+
function validateTelemetryBatchCardinality(resolved, source, inputPointCount) {
|
|
4053
|
+
if (source.sourceRowCount === 0) {
|
|
4054
|
+
throw new MaterializationValidationError("Projection telemetry batches must consume at least one source row; an empty dataset produces no batch commit.");
|
|
4055
|
+
}
|
|
4056
|
+
const mappedPropertyCount = resolved.ownership.telemetry.length;
|
|
4057
|
+
if (mappedPropertyCount === 0) {
|
|
4058
|
+
throw new MaterializationValidationError(`Telemetry projection '${resolved.projectionId}' must own at least one telemetry property.`);
|
|
4059
|
+
}
|
|
4060
|
+
const sourceRowsEmitted = source.sourceRowCount - source.sourceRowsSkipped;
|
|
4061
|
+
const maximumPointCount = sourceRowsEmitted * mappedPropertyCount;
|
|
4062
|
+
if (!Number.isSafeInteger(maximumPointCount)) {
|
|
4063
|
+
throw new MaterializationValidationError(`Telemetry projection '${resolved.projectionId}' batch point capacity exceeds the safe integer range.`);
|
|
4064
|
+
}
|
|
4065
|
+
if (inputPointCount < sourceRowsEmitted || inputPointCount > maximumPointCount) {
|
|
4066
|
+
throw new MaterializationValidationError(`Telemetry projection '${resolved.projectionId}' must emit between ${sourceRowsEmitted} and ${maximumPointCount} points for ${source.sourceRowCount} source rows with ${source.sourceRowsSkipped} skipped.`);
|
|
4067
|
+
}
|
|
4068
|
+
}
|
|
3912
4069
|
function validateTelemetryProjectionDataset(resolved, source) {
|
|
3913
4070
|
if (resolved.datasetId === source.datasetVersion.datasetId)
|
|
3914
4071
|
return;
|
|
@@ -4171,4 +4328,4 @@ function createOntologyMaterializer(input) {
|
|
|
4171
4328
|
}
|
|
4172
4329
|
export { computeOntologyRevision, computeProjectionRevision, computeProjectionOwnershipHash, ProjectionRegistry, createActionIdempotencyKey, createRuntimeIdempotencyKey, createProjectionIdempotencyKey, createRuntimeTelemetryIdempotencyKey, createProjectionTelemetryIdempotencyKey, createCommitIdentity, timestampCommitIdentity, createTimedCommitIdentity, createProjectionMaterializationId, createLinkScopeFingerprint, normalizeJsonProperties, normalizeOntologyEditCommit, normalizeProjectionExecution, normalizeProjectionSourceEntry, normalizeTelemetryAppend, OntologyMaterializer, createOntologyMaterializer };
|
|
4173
4330
|
|
|
4174
|
-
//# debugId=
|
|
4331
|
+
//# debugId=D96E192C1BE0917864756E2164756E21
|