@sixb/core 0.1.3 → 0.1.5
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.d.ts +2 -2
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +17 -18
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/read-facade.d.ts +10 -2
- package/dist/actions/read-facade.d.ts.map +1 -1
- package/dist/actions/types/context.d.ts +45 -2
- package/dist/actions/types/context.d.ts.map +1 -1
- package/dist/actions/worker.js +4 -4
- package/dist/actions/worker.js.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/ids.d.ts +2 -0
- package/dist/agents/ids.d.ts.map +1 -1
- package/dist/agents/index.d.ts +6 -5
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +42 -37
- package/dist/agents/index.js.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 +4 -2
- package/dist/agents/streams.js.map +1 -1
- package/dist/agents/types.d.ts +11 -0
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/agents/validation.d.ts +1 -1
- package/dist/agents/validation.d.ts.map +1 -1
- package/dist/auth/index.js +7 -3
- 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 +30 -31
- package/dist/bootstrap/index.js.map +1 -1
- package/dist/{chunk-d6y2wsfg.js → chunk-1q02e95s.js} +12 -7
- package/dist/{chunk-d6y2wsfg.js.map → chunk-1q02e95s.js.map} +4 -3
- package/dist/{chunk-c6cfqydk.js → chunk-4h947jd8.js} +1 -1
- package/dist/{chunk-gqdd7508.js → chunk-4rh2m6zg.js} +1 -1
- package/dist/{chunk-f1cyvnrk.js → chunk-6d5xdj1q.js} +259 -9
- package/dist/chunk-6d5xdj1q.js.map +14 -0
- package/dist/{chunk-fmx1sz2h.js → chunk-72q2y8hn.js} +3 -3
- package/dist/{chunk-fmx1sz2h.js.map → chunk-72q2y8hn.js.map} +3 -3
- package/dist/{chunk-ttba8x6z.js → chunk-78c6xvyr.js} +68 -3
- package/dist/chunk-78c6xvyr.js.map +15 -0
- package/dist/{chunk-wb4051cx.js → chunk-819wnjz8.js} +11 -5
- package/dist/chunk-819wnjz8.js.map +12 -0
- package/dist/{chunk-177ed2mp.js → chunk-84h6qhmp.js} +233 -97
- package/dist/{chunk-177ed2mp.js.map → chunk-84h6qhmp.js.map} +9 -9
- package/dist/{chunk-pxtrxm3p.js → chunk-a09jx26t.js} +1 -1
- package/dist/{chunk-bv41fmjn.js → chunk-am6eczah.js} +59 -22
- package/dist/{chunk-bv41fmjn.js.map → chunk-am6eczah.js.map} +8 -7
- package/dist/{chunk-zpw39qhj.js → chunk-dm72y8wt.js} +25 -2
- package/dist/chunk-dm72y8wt.js.map +10 -0
- package/dist/{chunk-kqxgf6kv.js → chunk-drjqm1aa.js} +16 -1
- package/dist/{chunk-kqxgf6kv.js.map → chunk-drjqm1aa.js.map} +3 -3
- package/dist/chunk-dysw7nsm.js.map +1 -1
- package/dist/{chunk-4p9rh7jj.js → chunk-ea73pzk7.js} +1 -1
- package/dist/{chunk-4aw0jwk0.js → chunk-f6erf2vv.js} +1 -1
- package/dist/{chunk-4z3n1dzt.js → chunk-f83ka50g.js} +131 -25
- package/dist/chunk-f83ka50g.js.map +23 -0
- package/dist/{chunk-c8bw2b6c.js → chunk-gadsm794.js} +2 -2
- package/dist/{chunk-1ywq4hzk.js → chunk-h6h91mfy.js} +8 -10
- package/dist/{chunk-1ywq4hzk.js.map → chunk-h6h91mfy.js.map} +2 -2
- package/dist/{chunk-n5x5y80a.js → chunk-nzw7sm3b.js} +2 -2
- 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-261ag4t4.js → chunk-r0rry8dn.js} +3 -3
- package/dist/{chunk-88ppkr54.js → chunk-rte5sm3z.js} +26 -2
- package/dist/chunk-rte5sm3z.js.map +12 -0
- package/dist/chunk-t0jjkep3.js.map +1 -1
- package/dist/{chunk-ettb0cy4.js → chunk-tbv03sx2.js} +59 -29
- package/dist/{chunk-ettb0cy4.js.map → chunk-tbv03sx2.js.map} +5 -5
- package/dist/{chunk-d2adj15j.js → chunk-tkdscva6.js} +1 -1
- package/dist/{chunk-xmggaxg4.js → chunk-v0egge8b.js} +201 -38
- package/dist/{chunk-xmggaxg4.js.map → chunk-v0egge8b.js.map} +8 -6
- package/dist/{chunk-z8j83gzd.js → chunk-x2yw73hy.js} +1 -1
- package/dist/{chunk-qer6am8w.js → chunk-xdf9yswn.js} +1 -1
- package/dist/{chunk-3rsf30p4.js → chunk-z3ga9q5m.js} +18 -21
- package/dist/{chunk-3rsf30p4.js.map → chunk-z3ga9q5m.js.map} +4 -5
- package/dist/{chunk-km4rkj4t.js → chunk-zp2v2rv6.js} +3 -3
- package/dist/execution/agent.js +26 -27
- package/dist/execution/agent.js.map +1 -1
- package/dist/execution/primitive.js +26 -27
- package/dist/execution/primitive.js.map +2 -2
- package/dist/execution/request.js +27 -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 +54 -55
- 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/materializer/index.js +15 -16
- package/dist/materializer/index.js.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 +19 -20
- 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/ontology/internal.d.ts +1 -1
- package/dist/ontology/internal.d.ts.map +1 -1
- package/dist/ontology/internal.js +14 -6
- package/dist/ontology/internal.js.map +3 -3
- package/dist/ontology/json-schema.d.ts +10 -0
- package/dist/ontology/json-schema.d.ts.map +1 -1
- package/dist/pipelines/index.js +15 -16
- package/dist/pipelines/index.js.map +1 -1
- package/dist/projections/builders.d.ts +33 -4
- package/dist/projections/builders.d.ts.map +1 -1
- package/dist/projections/index.d.ts +1 -1
- package/dist/projections/index.d.ts.map +1 -1
- package/dist/projections/internal.js +15 -16
- 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/types.d.ts +12 -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/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 +4 -0
- package/dist/storage/agents/in-memory.d.ts.map +1 -1
- package/dist/storage/agents/provider.js +9 -5
- package/dist/storage/agents/provider.js.map +1 -1
- package/dist/storage/agents/types.d.ts +5 -0
- package/dist/storage/agents/types.d.ts.map +1 -1
- package/dist/storage/ai-cost/provider.js +1 -1
- 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/index.d.ts +3 -2
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +19 -14
- 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/provider.js +1 -1
- package/dist/storage/workflow-runs/provider.js +9 -5
- package/dist/storage/workflow-runs/provider.js.map +1 -1
- package/dist/syncs/index.js +15 -16
- package/dist/syncs/index.js.map +1 -1
- package/dist/testing/agent-storage-contract.d.ts.map +1 -1
- 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.js +455 -40
- package/dist/testing/index.js.map +7 -7
- package/dist/testing/lake-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 +13 -14
- package/dist/webhooks/internal.js.map +2 -2
- package/dist/workflows/index.js +27 -28
- package/dist/workflows/index.js.map +1 -1
- package/package.json +1 -1
- package/src/actions/index.ts +10 -1
- package/src/actions/read-facade.ts +125 -3
- package/src/actions/types/context.ts +69 -2
- package/src/agents/builders.ts +3 -3
- package/src/agents/context-compaction.ts +261 -0
- package/src/agents/ids.ts +5 -0
- package/src/agents/index.ts +18 -9
- package/src/agents/streams.ts +56 -0
- package/src/agents/types.ts +12 -0
- package/src/agents/validation.ts +39 -5
- package/src/http/api-routes.ts +7 -7
- package/src/index.ts +19 -0
- package/src/lake-storage/types.ts +2 -1
- 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/ontology/internal.ts +1 -1
- package/src/ontology/json-schema.ts +27 -5
- package/src/projections/builders.ts +220 -15
- package/src/projections/index.ts +1 -0
- package/src/projections/ownership.ts +5 -5
- package/src/projections/registry.ts +9 -3
- package/src/projections/revision.ts +31 -5
- package/src/projections/run-dispatch.ts +10 -1
- package/src/projections/types.ts +13 -9
- package/src/projections/validation.ts +61 -19
- package/src/query.ts +2 -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 +15 -0
- package/src/storage/agents/types.ts +5 -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/index.ts +11 -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/provider-header-validation.ts +2 -2
- package/src/storage/timeseries/store.ts +6 -6
- package/src/testing/agent-storage-contract.ts +12 -0
- package/src/testing/ai-usage-storage-contract.ts +35 -0
- package/src/testing/effective-storage-contract.ts +194 -4
- package/src/testing/lake-storage-contract.ts +56 -0
- package/src/testing/object-query-contract.ts +208 -1
- package/dist/agents/prompt.d.ts +0 -21
- package/dist/agents/prompt.d.ts.map +0 -1
- package/dist/chunk-4z3n1dzt.js.map +0 -23
- 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-f1cyvnrk.js.map +0 -13
- package/dist/chunk-ttba8x6z.js.map +0 -15
- package/dist/chunk-wb4051cx.js.map +0 -12
- package/dist/chunk-zpw39qhj.js.map +0 -10
- package/src/agents/prompt.ts +0 -85
- /package/dist/{chunk-c6cfqydk.js.map → chunk-4h947jd8.js.map} +0 -0
- /package/dist/{chunk-gqdd7508.js.map → chunk-4rh2m6zg.js.map} +0 -0
- /package/dist/{chunk-pxtrxm3p.js.map → chunk-a09jx26t.js.map} +0 -0
- /package/dist/{chunk-4p9rh7jj.js.map → chunk-ea73pzk7.js.map} +0 -0
- /package/dist/{chunk-4aw0jwk0.js.map → chunk-f6erf2vv.js.map} +0 -0
- /package/dist/{chunk-c8bw2b6c.js.map → chunk-gadsm794.js.map} +0 -0
- /package/dist/{chunk-n5x5y80a.js.map → chunk-nzw7sm3b.js.map} +0 -0
- /package/dist/{chunk-261ag4t4.js.map → chunk-r0rry8dn.js.map} +0 -0
- /package/dist/{chunk-d2adj15j.js.map → chunk-tkdscva6.js.map} +0 -0
- /package/dist/{chunk-z8j83gzd.js.map → chunk-x2yw73hy.js.map} +0 -0
- /package/dist/{chunk-qer6am8w.js.map → chunk-xdf9yswn.js.map} +0 -0
- /package/dist/{chunk-km4rkj4t.js.map → chunk-zp2v2rv6.js.map} +0 -0
|
@@ -24,6 +24,7 @@ import type {
|
|
|
24
24
|
ProjectionTarget,
|
|
25
25
|
SourceEditConflictResolution,
|
|
26
26
|
TelemetryProjectionDefinition,
|
|
27
|
+
TelemetryProjectionPropertyMapping,
|
|
27
28
|
} from "./types"
|
|
28
29
|
import {
|
|
29
30
|
validateAndLowerLinkMapping,
|
|
@@ -186,6 +187,18 @@ type TelemetryPropertyToken<TObjectTypeId extends string = string> = PropertyTok
|
|
|
186
187
|
Property & { readonly mode: "telemetry" }
|
|
187
188
|
>
|
|
188
189
|
|
|
190
|
+
type TelemetryPropertyOf<TObjectType extends ObjectType> = Extract<
|
|
191
|
+
TObjectType["properties"][number],
|
|
192
|
+
{ readonly mode: "telemetry" }
|
|
193
|
+
>
|
|
194
|
+
|
|
195
|
+
type TelemetryPropertyIdOf<TObjectType extends ObjectType> = TelemetryPropertyOf<TObjectType>["id"]
|
|
196
|
+
|
|
197
|
+
type TelemetryPropertyById<
|
|
198
|
+
TObjectType extends ObjectType,
|
|
199
|
+
TPropertyId extends TelemetryPropertyIdOf<TObjectType>,
|
|
200
|
+
> = Extract<TelemetryPropertyOf<TObjectType>, { readonly id: TPropertyId }>
|
|
201
|
+
|
|
189
202
|
type TelemetryProjectionPointMapping<
|
|
190
203
|
TPropertyToken extends TelemetryPropertyToken,
|
|
191
204
|
TDataset extends DatasetDefinition,
|
|
@@ -203,6 +216,58 @@ type ExactTelemetryProjectionPointMapping<TMapping> = TMapping & {
|
|
|
203
216
|
readonly [TKey in Exclude<keyof TMapping, "objectId" | "at" | "value" | "unit">]: never
|
|
204
217
|
}
|
|
205
218
|
|
|
219
|
+
type TelemetryProjectionPropertyInput<
|
|
220
|
+
TProperty extends Property,
|
|
221
|
+
TDataset extends DatasetDefinition,
|
|
222
|
+
> =
|
|
223
|
+
| DatasetColumnNameCompatibleWithSchema<TDataset, TProperty["schema"]>
|
|
224
|
+
| {
|
|
225
|
+
readonly value: DatasetColumnNameCompatibleWithSchema<TDataset, TProperty["schema"]>
|
|
226
|
+
readonly unit: StringDatasetColumnNameOf<TDataset>
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
type TelemetryProjectionPropertiesMapping<
|
|
230
|
+
TObjectType extends ObjectType,
|
|
231
|
+
TDataset extends DatasetDefinition,
|
|
232
|
+
> = {
|
|
233
|
+
readonly [TPropertyId in TelemetryPropertyIdOf<TObjectType>]?: TelemetryProjectionPropertyInput<
|
|
234
|
+
TelemetryPropertyById<TObjectType, TPropertyId>,
|
|
235
|
+
TDataset
|
|
236
|
+
>
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
type ExactTelemetryProjectionPropertiesMapping<
|
|
240
|
+
TObjectType extends ObjectType,
|
|
241
|
+
TMapping,
|
|
242
|
+
> = TMapping & {
|
|
243
|
+
readonly [TKey in Exclude<keyof TMapping, TelemetryPropertyIdOf<TObjectType>>]: never
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
type ExactTelemetryProjectionPropertyInputs<TMapping> = {
|
|
247
|
+
readonly [TPropertyId in keyof TMapping]: TMapping[TPropertyId] extends object
|
|
248
|
+
? TMapping[TPropertyId] & {
|
|
249
|
+
readonly [TKey in Exclude<keyof TMapping[TPropertyId], "value" | "unit">]: never
|
|
250
|
+
}
|
|
251
|
+
: TMapping[TPropertyId]
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
type NonEmptyTelemetryProjectionProperties<TMapping> = keyof TMapping extends never
|
|
255
|
+
? never
|
|
256
|
+
: TMapping
|
|
257
|
+
|
|
258
|
+
type TelemetryProjectionPropertiesPointMapping<
|
|
259
|
+
TObjectType extends ObjectType,
|
|
260
|
+
TDataset extends DatasetDefinition,
|
|
261
|
+
TProperties,
|
|
262
|
+
> = {
|
|
263
|
+
readonly objectId: StringDatasetColumnNameOf<TDataset>
|
|
264
|
+
readonly at: DateLikeDatasetColumnNameOf<TDataset>
|
|
265
|
+
readonly properties: NonEmptyTelemetryProjectionProperties<
|
|
266
|
+
ExactTelemetryProjectionPropertiesMapping<TObjectType, TProperties> &
|
|
267
|
+
ExactTelemetryProjectionPropertyInputs<TProperties>
|
|
268
|
+
>
|
|
269
|
+
}
|
|
270
|
+
|
|
206
271
|
type ForeignKeyFromSourceProperty = Omit<
|
|
207
272
|
ForeignKeyDescriptor,
|
|
208
273
|
"sourcePropertyId" | "sourceField"
|
|
@@ -284,19 +349,22 @@ function isForeignKeyDescriptor(value: unknown): value is ForeignKeyDescriptor {
|
|
|
284
349
|
|
|
285
350
|
// ── defineProjection ─────────────────────────────────────────
|
|
286
351
|
|
|
287
|
-
interface
|
|
352
|
+
interface ObjectTypeProjectionSourceBuilder<TObjectType extends ObjectType> {
|
|
288
353
|
fromDataset<const TDataset extends DatasetDefinition>(
|
|
289
354
|
dataset: TDataset
|
|
290
|
-
):
|
|
355
|
+
): ObjectTypeProjectionDatasetBuilder<TObjectType, TDataset>
|
|
291
356
|
}
|
|
292
357
|
|
|
293
|
-
interface
|
|
358
|
+
interface ObjectTypeProjectionDatasetBuilder<
|
|
294
359
|
TObjectType extends ObjectType,
|
|
295
360
|
TDataset extends DatasetDefinition,
|
|
296
361
|
> {
|
|
297
362
|
properties<const TMapping extends ProjectionMappingFor<TObjectType, TDataset>>(
|
|
298
363
|
mapping: ExactProjectionMapping<TObjectType, TMapping>
|
|
299
364
|
): ObjectProjectionBuilder<TObjectType, TDataset>
|
|
365
|
+
points<const TProperties extends TelemetryProjectionPropertiesMapping<TObjectType, TDataset>>(
|
|
366
|
+
mapping: TelemetryProjectionPropertiesPointMapping<TObjectType, TDataset, TProperties>
|
|
367
|
+
): TelemetryProjectionDefinition
|
|
300
368
|
}
|
|
301
369
|
|
|
302
370
|
export type ObjectProjectionConflictResolution<TDataset extends DatasetDefinition> =
|
|
@@ -338,7 +406,7 @@ export interface ObjectProjectionBuilder<
|
|
|
338
406
|
export function defineProjection<const TObjectType extends ObjectType>(
|
|
339
407
|
id: string,
|
|
340
408
|
objectType: TObjectType
|
|
341
|
-
):
|
|
409
|
+
): ObjectTypeProjectionSourceBuilder<TObjectType>
|
|
342
410
|
export function defineProjection<
|
|
343
411
|
TObjectTypeId extends string,
|
|
344
412
|
TLinkId extends string,
|
|
@@ -355,24 +423,24 @@ export function defineProjection(
|
|
|
355
423
|
id: string,
|
|
356
424
|
target: ObjectType | LinkToken<string, string, string> | TelemetryPropertyToken
|
|
357
425
|
):
|
|
358
|
-
|
|
|
426
|
+
| ObjectTypeProjectionSourceBuilder<ObjectType>
|
|
359
427
|
| LinkProjectionSourceBuilder
|
|
360
428
|
| TelemetryProjectionSourceBuilder<TelemetryPropertyToken> {
|
|
361
429
|
if ("link" in target) return buildLinkProjection(id, target)
|
|
362
430
|
if ("property" in target) return buildTelemetryProjection(id, target)
|
|
363
|
-
return
|
|
431
|
+
return buildObjectTypeProjection(id, target)
|
|
364
432
|
}
|
|
365
433
|
|
|
366
|
-
function
|
|
434
|
+
function buildObjectTypeProjection<const TObjectType extends ObjectType>(
|
|
367
435
|
id: string,
|
|
368
436
|
objectType: TObjectType
|
|
369
|
-
):
|
|
437
|
+
): ObjectTypeProjectionSourceBuilder<TObjectType> {
|
|
370
438
|
assertNonEmpty(id, "id")
|
|
371
439
|
|
|
372
440
|
return {
|
|
373
441
|
fromDataset<const TDataset extends DatasetDefinition>(
|
|
374
442
|
dataset: TDataset
|
|
375
|
-
):
|
|
443
|
+
): ObjectTypeProjectionDatasetBuilder<TObjectType, TDataset> {
|
|
376
444
|
assertProjectionDataset(dataset)
|
|
377
445
|
const datasetId = dataset.id
|
|
378
446
|
|
|
@@ -392,6 +460,29 @@ function buildObjectProjection<const TObjectType extends ObjectType>(
|
|
|
392
460
|
conflictResolution: { strategy: "editsWin" },
|
|
393
461
|
})
|
|
394
462
|
},
|
|
463
|
+
points<
|
|
464
|
+
const TProperties extends TelemetryProjectionPropertiesMapping<TObjectType, TDataset>,
|
|
465
|
+
>(
|
|
466
|
+
mapping: TelemetryProjectionPropertiesPointMapping<TObjectType, TDataset, TProperties>
|
|
467
|
+
): TelemetryProjectionDefinition {
|
|
468
|
+
const pointMapping = lowerTelemetryPropertiesPointMapping(
|
|
469
|
+
objectType,
|
|
470
|
+
mapping as {
|
|
471
|
+
readonly objectId?: string
|
|
472
|
+
readonly at?: string
|
|
473
|
+
readonly properties?: Readonly<Record<string, unknown>>
|
|
474
|
+
}
|
|
475
|
+
)
|
|
476
|
+
return {
|
|
477
|
+
_tag: "TelemetryProjectionDefinition",
|
|
478
|
+
id,
|
|
479
|
+
objectTypeId: objectType.id,
|
|
480
|
+
datasetId,
|
|
481
|
+
objectIdField: pointMapping.objectId,
|
|
482
|
+
atField: pointMapping.at,
|
|
483
|
+
properties: pointMapping.properties,
|
|
484
|
+
}
|
|
485
|
+
},
|
|
395
486
|
}
|
|
396
487
|
},
|
|
397
488
|
}
|
|
@@ -505,12 +596,15 @@ function buildTelemetryProjection<const TPropertyToken extends TelemetryProperty
|
|
|
505
596
|
_tag: "TelemetryProjectionDefinition",
|
|
506
597
|
id,
|
|
507
598
|
objectTypeId: propertyToken.objectTypeId,
|
|
508
|
-
propertyId: propertyToken.id,
|
|
509
599
|
datasetId,
|
|
510
600
|
objectIdField: pointMapping.objectId,
|
|
511
601
|
atField: pointMapping.at,
|
|
512
|
-
|
|
513
|
-
|
|
602
|
+
properties: {
|
|
603
|
+
[propertyToken.id]: {
|
|
604
|
+
valueField: pointMapping.value,
|
|
605
|
+
...(pointMapping.unit !== undefined ? { unitField: pointMapping.unit } : {}),
|
|
606
|
+
},
|
|
607
|
+
},
|
|
514
608
|
}
|
|
515
609
|
},
|
|
516
610
|
}
|
|
@@ -571,6 +665,109 @@ function lowerTelemetryPointMapping(mapping: {
|
|
|
571
665
|
}
|
|
572
666
|
}
|
|
573
667
|
|
|
668
|
+
function lowerTelemetryPropertiesPointMapping(
|
|
669
|
+
objectType: ObjectType,
|
|
670
|
+
mapping: {
|
|
671
|
+
readonly objectId?: string
|
|
672
|
+
readonly at?: string
|
|
673
|
+
readonly properties?: Readonly<Record<string, unknown>>
|
|
674
|
+
}
|
|
675
|
+
): {
|
|
676
|
+
readonly objectId: string
|
|
677
|
+
readonly at: string
|
|
678
|
+
readonly properties: Readonly<Record<string, TelemetryProjectionPropertyMapping>>
|
|
679
|
+
} {
|
|
680
|
+
const allowedKeys = new Set(["objectId", "at", "properties"])
|
|
681
|
+
for (const key of Object.keys(mapping)) {
|
|
682
|
+
if (!allowedKeys.has(key)) {
|
|
683
|
+
throw new ProjectionValidationError(
|
|
684
|
+
`Telemetry projection point mapping contains unknown key '${key}'.`
|
|
685
|
+
)
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
if (mapping.objectId === undefined) {
|
|
690
|
+
throw new ProjectionValidationError("Telemetry projection point mapping requires objectId.")
|
|
691
|
+
}
|
|
692
|
+
if (mapping.at === undefined) {
|
|
693
|
+
throw new ProjectionValidationError("Telemetry projection point mapping requires at.")
|
|
694
|
+
}
|
|
695
|
+
if (mapping.properties === undefined) {
|
|
696
|
+
throw new ProjectionValidationError("Telemetry projection point mapping requires properties.")
|
|
697
|
+
}
|
|
698
|
+
if (!isRecord(mapping.properties)) {
|
|
699
|
+
throw new ProjectionValidationError(
|
|
700
|
+
"Telemetry projection point mapping properties must be an object."
|
|
701
|
+
)
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
assertNonEmpty(mapping.objectId, "objectId field")
|
|
705
|
+
assertNonEmpty(mapping.at, "at field")
|
|
706
|
+
|
|
707
|
+
const propertyEntries = Object.entries(mapping.properties)
|
|
708
|
+
if (propertyEntries.length === 0) {
|
|
709
|
+
throw new ProjectionValidationError(
|
|
710
|
+
"Telemetry projection point mapping requires at least one property."
|
|
711
|
+
)
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
const propertiesById = new Map(objectType.properties.map((property) => [property.id, property]))
|
|
715
|
+
const properties: Record<string, TelemetryProjectionPropertyMapping> = {}
|
|
716
|
+
for (const [propertyId, input] of propertyEntries) {
|
|
717
|
+
const property = propertiesById.get(propertyId)
|
|
718
|
+
if (!property) {
|
|
719
|
+
throw new ProjectionValidationError(
|
|
720
|
+
`Property '${propertyId}' does not exist on object type '${objectType.id}'.`
|
|
721
|
+
)
|
|
722
|
+
}
|
|
723
|
+
if (property.mode !== "telemetry") {
|
|
724
|
+
throw new ProjectionValidationError(
|
|
725
|
+
`Projection property '${objectType.id}.${propertyId}' must be telemetry-enabled.`
|
|
726
|
+
)
|
|
727
|
+
}
|
|
728
|
+
properties[propertyId] = lowerTelemetryPropertyMapping(propertyId, input)
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
return { objectId: mapping.objectId, at: mapping.at, properties }
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
function lowerTelemetryPropertyMapping(
|
|
735
|
+
propertyId: string,
|
|
736
|
+
input: unknown
|
|
737
|
+
): TelemetryProjectionPropertyMapping {
|
|
738
|
+
if (typeof input === "string") {
|
|
739
|
+
assertNonEmpty(input, `property '${propertyId}' value field`)
|
|
740
|
+
return { valueField: input }
|
|
741
|
+
}
|
|
742
|
+
if (!isRecord(input)) {
|
|
743
|
+
throw new ProjectionValidationError(
|
|
744
|
+
`Telemetry projection property '${propertyId}' must map a value column or value/unit columns.`
|
|
745
|
+
)
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
const allowedKeys = new Set(["value", "unit"])
|
|
749
|
+
for (const key of Object.keys(input)) {
|
|
750
|
+
if (!allowedKeys.has(key)) {
|
|
751
|
+
throw new ProjectionValidationError(
|
|
752
|
+
`Telemetry projection property '${propertyId}' contains unknown key '${key}'.`
|
|
753
|
+
)
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
if (typeof input.value !== "string") {
|
|
757
|
+
throw new ProjectionValidationError(
|
|
758
|
+
`Telemetry projection property '${propertyId}' requires a value field.`
|
|
759
|
+
)
|
|
760
|
+
}
|
|
761
|
+
if (typeof input.unit !== "string") {
|
|
762
|
+
throw new ProjectionValidationError(
|
|
763
|
+
`Telemetry projection property '${propertyId}' requires a unit field.`
|
|
764
|
+
)
|
|
765
|
+
}
|
|
766
|
+
assertNonEmpty(input.value, `property '${propertyId}' value field`)
|
|
767
|
+
assertNonEmpty(input.unit, `property '${propertyId}' unit field`)
|
|
768
|
+
return { valueField: input.value, unitField: input.unit }
|
|
769
|
+
}
|
|
770
|
+
|
|
574
771
|
// ── fromForeignKey ───────────────────────────────────────────
|
|
575
772
|
|
|
576
773
|
/**
|
|
@@ -765,12 +962,20 @@ export function isTelemetryProjectionDefinition(
|
|
|
765
962
|
value._tag === "TelemetryProjectionDefinition" &&
|
|
766
963
|
typeof value.id === "string" &&
|
|
767
964
|
typeof value.objectTypeId === "string" &&
|
|
768
|
-
typeof value.propertyId === "string" &&
|
|
769
965
|
typeof value.datasetId === "string" &&
|
|
770
966
|
typeof value.objectIdField === "string" &&
|
|
771
967
|
typeof value.atField === "string" &&
|
|
772
|
-
|
|
773
|
-
|
|
968
|
+
isTelemetryProjectionProperties(value.properties)
|
|
969
|
+
)
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
function isTelemetryProjectionProperties(value: unknown): boolean {
|
|
973
|
+
if (!isRecord(value) || Object.keys(value).length === 0) return false
|
|
974
|
+
return Object.values(value).every(
|
|
975
|
+
(mapping) =>
|
|
976
|
+
isRecord(mapping) &&
|
|
977
|
+
typeof mapping.valueField === "string" &&
|
|
978
|
+
(mapping.unitField === undefined || typeof mapping.unitField === "string")
|
|
774
979
|
)
|
|
775
980
|
}
|
|
776
981
|
|
package/src/projections/index.ts
CHANGED
|
@@ -42,12 +42,12 @@ export function computeProjectionOwnership(
|
|
|
42
42
|
return freezeOwnership({
|
|
43
43
|
objects: [],
|
|
44
44
|
links: [],
|
|
45
|
-
telemetry:
|
|
46
|
-
|
|
45
|
+
telemetry: Object.keys(projection.properties)
|
|
46
|
+
.sort(compareStrings)
|
|
47
|
+
.map((propertyId) => ({
|
|
47
48
|
objectTypeId: projection.objectTypeId,
|
|
48
|
-
propertyId
|
|
49
|
-
},
|
|
50
|
-
],
|
|
49
|
+
propertyId,
|
|
50
|
+
})),
|
|
51
51
|
})
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -273,12 +273,18 @@ function cloneTelemetryProjectionDefinition(
|
|
|
273
273
|
_tag: "TelemetryProjectionDefinition",
|
|
274
274
|
id: projection.id,
|
|
275
275
|
objectTypeId: projection.objectTypeId,
|
|
276
|
-
propertyId: projection.propertyId,
|
|
277
276
|
datasetId: projection.datasetId,
|
|
278
277
|
objectIdField: projection.objectIdField,
|
|
279
278
|
atField: projection.atField,
|
|
280
|
-
|
|
281
|
-
|
|
279
|
+
properties: Object.fromEntries(
|
|
280
|
+
Object.entries(projection.properties).map(([propertyId, mapping]) => [
|
|
281
|
+
propertyId,
|
|
282
|
+
{
|
|
283
|
+
valueField: mapping.valueField,
|
|
284
|
+
...(mapping.unitField !== undefined ? { unitField: mapping.unitField } : {}),
|
|
285
|
+
},
|
|
286
|
+
])
|
|
287
|
+
),
|
|
282
288
|
}
|
|
283
289
|
}
|
|
284
290
|
|
|
@@ -160,14 +160,38 @@ function normalizeProjectionDefinition(projection: ProjectionDefinition): JsonVa
|
|
|
160
160
|
targetField: projection.targetField,
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
|
+
const properties = Object.entries(projection.properties).sort(([left], [right]) =>
|
|
164
|
+
compareStrings(left, right)
|
|
165
|
+
)
|
|
166
|
+
if (properties.length === 1) {
|
|
167
|
+
const [propertyId, mapping] = properties[0]
|
|
168
|
+
// Preserve the pre-grouping semantic hash for one-property projections. The authoring form and
|
|
169
|
+
// lowered shape changed, but the source semantics did not; keeping the hash stable prevents a
|
|
170
|
+
// deployment from invalidating queued jobs or replaying completed dataset versions.
|
|
171
|
+
return {
|
|
172
|
+
kind: "telemetry",
|
|
173
|
+
objectTypeId: projection.objectTypeId,
|
|
174
|
+
propertyId,
|
|
175
|
+
objectIdField: projection.objectIdField,
|
|
176
|
+
atField: projection.atField,
|
|
177
|
+
valueField: mapping.valueField,
|
|
178
|
+
unitField: mapping.unitField ?? null,
|
|
179
|
+
}
|
|
180
|
+
}
|
|
163
181
|
return {
|
|
164
182
|
kind: "telemetry",
|
|
165
183
|
objectTypeId: projection.objectTypeId,
|
|
166
|
-
propertyId: projection.propertyId,
|
|
167
184
|
objectIdField: projection.objectIdField,
|
|
168
185
|
atField: projection.atField,
|
|
169
|
-
|
|
170
|
-
|
|
186
|
+
properties: Object.fromEntries(
|
|
187
|
+
properties.map(([propertyId, mapping]) => [
|
|
188
|
+
propertyId,
|
|
189
|
+
{
|
|
190
|
+
valueField: mapping.valueField,
|
|
191
|
+
unitField: mapping.unitField ?? null,
|
|
192
|
+
},
|
|
193
|
+
])
|
|
194
|
+
),
|
|
171
195
|
}
|
|
172
196
|
}
|
|
173
197
|
|
|
@@ -189,8 +213,10 @@ function projectionColumns(projection: ProjectionDefinition): Set<string> {
|
|
|
189
213
|
return new Set([
|
|
190
214
|
projection.objectIdField,
|
|
191
215
|
projection.atField,
|
|
192
|
-
projection.
|
|
193
|
-
|
|
216
|
+
...Object.values(projection.properties).flatMap((mapping) => [
|
|
217
|
+
mapping.valueField,
|
|
218
|
+
...(mapping.unitField === undefined ? [] : [mapping.unitField]),
|
|
219
|
+
]),
|
|
194
220
|
])
|
|
195
221
|
}
|
|
196
222
|
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
type ProjectionRunFailureCode,
|
|
24
24
|
} from "./types"
|
|
25
25
|
|
|
26
|
+
/** Target maximum mapped points per telemetry commit; a single-property projection reads 500 rows. */
|
|
26
27
|
export const PROJECTION_TELEMETRY_BATCH_SIZE = 500
|
|
27
28
|
|
|
28
29
|
export interface ProjectionRunDispatchInput {
|
|
@@ -403,11 +404,19 @@ function queueProjectionRun(
|
|
|
403
404
|
...common,
|
|
404
405
|
identity: input.identity,
|
|
405
406
|
target: { objectTypeId: input.projection.objectTypeId },
|
|
406
|
-
fixedBatchSize:
|
|
407
|
+
fixedBatchSize: telemetryProjectionBatchRowCount(input.projection),
|
|
407
408
|
})
|
|
408
409
|
}
|
|
409
410
|
}
|
|
410
411
|
|
|
412
|
+
function telemetryProjectionBatchRowCount(
|
|
413
|
+
projection: Extract<ProjectionDefinition, { readonly _tag: "TelemetryProjectionDefinition" }>
|
|
414
|
+
): number {
|
|
415
|
+
const mappedPropertyCount = Object.keys(projection.properties).length
|
|
416
|
+
if (mappedPropertyCount === 0) throw invalidProjectionDefinition(projection.id)
|
|
417
|
+
return Math.max(1, Math.floor(PROJECTION_TELEMETRY_BATCH_SIZE / mappedPropertyCount))
|
|
418
|
+
}
|
|
419
|
+
|
|
411
420
|
function requeueProjectionRun(
|
|
412
421
|
storage: NonNullable<Storage["projectionRuns"]>,
|
|
413
422
|
run: ProjectionRunRecord,
|
package/src/projections/types.ts
CHANGED
|
@@ -84,28 +84,32 @@ export interface LinkProjectionDefinition {
|
|
|
84
84
|
readonly targetField: string
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
/** Dataset columns that produce one telemetry property value. */
|
|
88
|
+
export interface TelemetryProjectionPropertyMapping {
|
|
89
|
+
/** Dataset column holding the telemetry value. */
|
|
90
|
+
readonly valueField: string
|
|
91
|
+
/** Dataset column holding the telemetry unit, when the property requires one. */
|
|
92
|
+
readonly unitField?: string
|
|
93
|
+
}
|
|
94
|
+
|
|
87
95
|
/**
|
|
88
96
|
* Lowered, serializable definition for projecting dataset rows into telemetry history.
|
|
89
97
|
*
|
|
90
|
-
* Each row
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* value, and optional unit.
|
|
98
|
+
* Each row shares one target object id and observation timestamp, then contributes up to one
|
|
99
|
+
* telemetry point for every mapped property. A property-token projection is lowered to the same
|
|
100
|
+
* shape with one entry, so execution and ownership have one canonical contract.
|
|
94
101
|
*/
|
|
95
102
|
export interface TelemetryProjectionDefinition {
|
|
96
103
|
readonly _tag: "TelemetryProjectionDefinition"
|
|
97
104
|
readonly id: string
|
|
98
105
|
readonly objectTypeId: string
|
|
99
|
-
readonly propertyId: string
|
|
100
106
|
readonly datasetId: string
|
|
101
107
|
/** Dataset column holding the target object's primary id. */
|
|
102
108
|
readonly objectIdField: string
|
|
103
109
|
/** Dataset column holding the telemetry observation timestamp. */
|
|
104
110
|
readonly atField: string
|
|
105
|
-
/**
|
|
106
|
-
readonly
|
|
107
|
-
/** Dataset column holding the telemetry unit, when the property requires one. */
|
|
108
|
-
readonly unitField?: string
|
|
111
|
+
/** Maps telemetry property id -> value and optional unit dataset columns. */
|
|
112
|
+
readonly properties: Readonly<Record<string, TelemetryProjectionPropertyMapping>>
|
|
109
113
|
}
|
|
110
114
|
|
|
111
115
|
/** Union of all projection definition types. */
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
import type { DatasetDefinition } from "../datasets"
|
|
9
9
|
import type { OntologyDefinitionCatalog } from "../ontology"
|
|
10
|
-
import type { ObjectType, Property } from "../ontology/types"
|
|
10
|
+
import type { ObjectType, Property, ValueType } from "../ontology/types"
|
|
11
|
+
import { resolveSemanticType } from "../ontology/validation"
|
|
11
12
|
import { ProjectionValidationError } from "./errors"
|
|
12
13
|
import {
|
|
13
14
|
computeProjectionOwnership,
|
|
@@ -196,37 +197,29 @@ export function validateLinkProjectionTarget(linkToken: {
|
|
|
196
197
|
|
|
197
198
|
/**
|
|
198
199
|
* Validates a telemetry projection's field mapping against its dataset columns
|
|
199
|
-
* and object type:
|
|
200
|
+
* and object type: every mapped property exists and is telemetry-enabled, and
|
|
200
201
|
* every mapped field (objectId/at/value/unit) resolves to a real dataset column.
|
|
201
202
|
*
|
|
202
203
|
* Owned here so startup validation and the projection worker's pre-execution
|
|
203
204
|
* check share one implementation and cannot drift; the worker layers
|
|
204
205
|
* dataset-version column type compatibility on top of these rules. Returns the
|
|
205
|
-
* resolved telemetry
|
|
206
|
+
* resolved telemetry properties for callers that need their schemas.
|
|
206
207
|
*/
|
|
207
208
|
export function validateTelemetryProjectionFieldMapping(
|
|
208
209
|
projection: TelemetryProjectionDefinition,
|
|
209
210
|
objectType: { readonly id: string; readonly properties: readonly Property[] },
|
|
210
211
|
datasetColumnNames: ReadonlySet<string>,
|
|
212
|
+
valueTypesById: ReadonlyMap<string, ValueType>,
|
|
211
213
|
prefix: string
|
|
212
|
-
): Property {
|
|
213
|
-
const
|
|
214
|
-
if (
|
|
215
|
-
throw new ProjectionValidationError(
|
|
216
|
-
`${prefix}: unknown property "${projection.propertyId}" on type "${projection.objectTypeId}"`
|
|
217
|
-
)
|
|
218
|
-
}
|
|
219
|
-
if (property.mode !== "telemetry") {
|
|
220
|
-
throw new ProjectionValidationError(
|
|
221
|
-
`${prefix}: property "${projection.propertyId}" on type "${projection.objectTypeId}" must be telemetry-enabled`
|
|
222
|
-
)
|
|
214
|
+
): ReadonlyMap<string, Property> {
|
|
215
|
+
const mappedProperties = Object.entries(projection.properties)
|
|
216
|
+
if (mappedProperties.length === 0) {
|
|
217
|
+
throw new ProjectionValidationError(`${prefix}: must map at least one telemetry property`)
|
|
223
218
|
}
|
|
224
219
|
|
|
225
220
|
const mappedFields = [
|
|
226
221
|
["objectId", projection.objectIdField],
|
|
227
222
|
["at", projection.atField],
|
|
228
|
-
["value", projection.valueField],
|
|
229
|
-
...(projection.unitField !== undefined ? ([["unit", projection.unitField]] as const) : []),
|
|
230
223
|
] as const
|
|
231
224
|
for (const [fieldRole, columnName] of mappedFields) {
|
|
232
225
|
if (!datasetColumnNames.has(columnName)) {
|
|
@@ -237,7 +230,49 @@ export function validateTelemetryProjectionFieldMapping(
|
|
|
237
230
|
}
|
|
238
231
|
}
|
|
239
232
|
|
|
240
|
-
|
|
233
|
+
const propertiesById = new Map(objectType.properties.map((property) => [property.id, property]))
|
|
234
|
+
const resolvedProperties = new Map<string, Property>()
|
|
235
|
+
for (const [propertyId, mapping] of mappedProperties) {
|
|
236
|
+
const property = propertiesById.get(propertyId)
|
|
237
|
+
if (!property) {
|
|
238
|
+
throw new ProjectionValidationError(
|
|
239
|
+
`${prefix}: unknown property "${propertyId}" on type "${projection.objectTypeId}"`
|
|
240
|
+
)
|
|
241
|
+
}
|
|
242
|
+
if (property.mode !== "telemetry") {
|
|
243
|
+
throw new ProjectionValidationError(
|
|
244
|
+
`${prefix}: property "${propertyId}" on type "${projection.objectTypeId}" must be telemetry-enabled`
|
|
245
|
+
)
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
for (const [fieldRole, columnName] of [
|
|
249
|
+
["value", mapping.valueField],
|
|
250
|
+
...(mapping.unitField !== undefined ? ([["unit", mapping.unitField]] as const) : []),
|
|
251
|
+
] as const) {
|
|
252
|
+
if (!datasetColumnNames.has(columnName)) {
|
|
253
|
+
throw new ProjectionValidationError(
|
|
254
|
+
`${prefix}: property "${propertyId}" ${fieldRole} field "${columnName}" references ` +
|
|
255
|
+
`unknown dataset column on dataset "${projection.datasetId}"`
|
|
256
|
+
)
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const semanticType = resolveSemanticType(property, valueTypesById)
|
|
261
|
+
if (semanticType !== undefined && mapping.unitField === undefined) {
|
|
262
|
+
throw new ProjectionValidationError(
|
|
263
|
+
`${prefix}: property "${propertyId}" requires a unit field because it uses semantic type "${semanticType}"`
|
|
264
|
+
)
|
|
265
|
+
}
|
|
266
|
+
if (semanticType === undefined && mapping.unitField !== undefined) {
|
|
267
|
+
throw new ProjectionValidationError(
|
|
268
|
+
`${prefix}: property "${propertyId}" cannot map a unit field because it has no semantic type`
|
|
269
|
+
)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
resolvedProperties.set(propertyId, property)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return resolvedProperties
|
|
241
276
|
}
|
|
242
277
|
|
|
243
278
|
/**
|
|
@@ -262,8 +297,9 @@ export function validateTelemetryProjectionFieldMapping(
|
|
|
262
297
|
* For telemetry projections:
|
|
263
298
|
* 1. `datasetId` exists in the dataset registry.
|
|
264
299
|
* 2. `objectTypeId` exists in the type registry.
|
|
265
|
-
* 3.
|
|
300
|
+
* 3. Every mapped property exists on the object type and is telemetry-enabled.
|
|
266
301
|
* 4. Point mapping fields exist in the referenced dataset.
|
|
302
|
+
* 5. Unit mappings match each property's semantic type requirements.
|
|
267
303
|
*/
|
|
268
304
|
export interface ValidatedProjectionRecord<TDefinition extends ProjectionDefinition>
|
|
269
305
|
extends ProjectionOwnershipRecord<TDefinition> {
|
|
@@ -512,7 +548,13 @@ export function validateProjectionsAtStartup(
|
|
|
512
548
|
}
|
|
513
549
|
|
|
514
550
|
const datasetColumnNames = new Set(dataset.schema.columns.map((column) => column.name))
|
|
515
|
-
validateTelemetryProjectionFieldMapping(
|
|
551
|
+
validateTelemetryProjectionFieldMapping(
|
|
552
|
+
projection,
|
|
553
|
+
objectType,
|
|
554
|
+
datasetColumnNames,
|
|
555
|
+
ontology.getValueTypesById(),
|
|
556
|
+
prefix
|
|
557
|
+
)
|
|
516
558
|
validatedTelemetryProjections.push({
|
|
517
559
|
definition: projection,
|
|
518
560
|
dataset,
|
package/src/query.ts
CHANGED
|
@@ -28,6 +28,7 @@ export type {
|
|
|
28
28
|
ObjectQueryPredicateIn,
|
|
29
29
|
ObjectQueryPredicateNot,
|
|
30
30
|
ObjectQueryProject,
|
|
31
|
+
ObjectQueryRefs,
|
|
31
32
|
ObjectQueryResultShape,
|
|
32
33
|
ObjectQuerySet,
|
|
33
34
|
ObjectQuerySetOperation,
|
|
@@ -50,6 +51,7 @@ export type {
|
|
|
50
51
|
ObjectQueryExecutorListResult,
|
|
51
52
|
ObjectQueryExecutorRow,
|
|
52
53
|
} from "./objects/sdk/query-executor"
|
|
54
|
+
export type { ObjectRef } from "./ontology/refs"
|
|
53
55
|
export type {
|
|
54
56
|
LinkToken,
|
|
55
57
|
ObjectTypeWithPropertyTokens,
|
package/src/runtime/create.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type { SixbErrorHandler } from "../error-reporting/types"
|
|
|
11
11
|
import type { LakeStorage } from "../lake-storage"
|
|
12
12
|
import type { LoggerProvider, ObservabilityOptions } from "../logging"
|
|
13
13
|
import type { OntologyMaintenanceOptions } from "../maintenance"
|
|
14
|
+
import type { ModelCatalogInput } from "../models"
|
|
14
15
|
import type { PipelineDefinition } from "../pipelines/types"
|
|
15
16
|
import type { ProjectionDefinition } from "../projections/types"
|
|
16
17
|
import type { Queues } from "../queues"
|
|
@@ -45,6 +46,8 @@ export interface CreateSixbOptions {
|
|
|
45
46
|
actions?: readonly ActionDefinition[]
|
|
46
47
|
/** Agent definitions to register in addition to auto-discovered `agents/` exports. */
|
|
47
48
|
agents?: readonly AgentDefinition[]
|
|
49
|
+
/** Models this project allows Sixb to use. The first of each kind is the default. */
|
|
50
|
+
models?: ModelCatalogInput
|
|
48
51
|
datasets?: readonly DatasetDefinition[]
|
|
49
52
|
/** Connector definitions to register in addition to auto-discovered `connectors/` exports. */
|
|
50
53
|
connectors?: readonly ConnectorDefinition[]
|
|
@@ -118,6 +121,7 @@ export async function createSixb(
|
|
|
118
121
|
roles: [...(options.roles ?? []), ...definitions.roles],
|
|
119
122
|
membershipPolicies: [...(options.membershipPolicies ?? []), ...definitions.membershipPolicies],
|
|
120
123
|
agents: [...(options.agents ?? []), ...definitions.agents],
|
|
124
|
+
models: options.models,
|
|
121
125
|
auth: options.auth,
|
|
122
126
|
})
|
|
123
127
|
}
|