@timeax/digital-service-engine 0.0.3 → 0.0.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.
@@ -2,6 +2,381 @@ import { NodeProps } from 'reactflow';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import React, { ReactNode } from 'react';
4
4
 
5
+ interface ButtonValue {
6
+ id: string;
7
+ value: string | number;
8
+ service_id?: number;
9
+ pricing_role?: "base" | "utility";
10
+ meta?: Record<string, unknown> & UtilityMark & WithQuantityDefault;
11
+ }
12
+ type Scalar = string | number | boolean | ButtonValue | null;
13
+ type UtilityMode = "flat" | "per_quantity" | "per_value" | "percent";
14
+ type QuantityRule$1 = {
15
+ valueBy: "value" | "length" | "eval";
16
+ code?: string;
17
+ };
18
+ type UtilityLineItem = {
19
+ nodeId: string;
20
+ mode: UtilityMode;
21
+ rate: number;
22
+ inputs: {
23
+ quantity: number;
24
+ value?: Scalar | Scalar[];
25
+ valueBy?: "value" | "length" | "eval";
26
+ evalCodeUsed?: boolean;
27
+ };
28
+ };
29
+ type ServiceFallbacks = ServiceFallback;
30
+ type FallbackDiagnostics = {
31
+ scope: "node" | "global";
32
+ nodeId?: string;
33
+ primary: string | number;
34
+ candidate: string | number;
35
+ reasons: Array<"rate_violation" | "constraint_mismatch" | "unknown_service" | "ambiguous_context">;
36
+ };
37
+ type SnapshotContext = {
38
+ /** The single active tag id for this order */
39
+ tag: string;
40
+ /** Effective (post-propagation) constraints on that tag */
41
+ constraints: Partial<Record<"refill" | "cancel" | "dripfeed", boolean>>;
42
+ /**
43
+ * Per-node evaluation context:
44
+ * - For the active tag node itself: the same tag id.
45
+ * - For an option node: parent's field.bind_id must include this tag to be applicable; otherwise null.
46
+ * - For a field node (optional to include later): same rule as option, derived from field.bind_id.
47
+ */
48
+ nodeContexts: Record<string, string | null>;
49
+ /** Client pruning policy used (so server can mirror/compare). */
50
+ policy: {
51
+ ratePolicy: {
52
+ kind: "lte_primary" | "none";
53
+ thresholdPct?: number;
54
+ };
55
+ requireConstraintFit: boolean;
56
+ };
57
+ };
58
+ type OrderSnapshot = {
59
+ version: "1";
60
+ mode: "prod" | "dev";
61
+ builtAt: string;
62
+ selection: {
63
+ tag: string;
64
+ buttons: string[];
65
+ fields: Array<{
66
+ id: string;
67
+ type: string;
68
+ selectedOptions?: string[];
69
+ }>;
70
+ };
71
+ inputs: {
72
+ form: Record<string, Scalar | Scalar[]>;
73
+ selections: Record<string, string[]>;
74
+ };
75
+ quantity: number;
76
+ quantitySource: {
77
+ kind: "field" | "tag" | "option" | "default";
78
+ id?: string;
79
+ rule?: QuantityRule$1;
80
+ defaultedFromHost?: boolean;
81
+ };
82
+ min: number;
83
+ max: number;
84
+ services: Array<string | number>;
85
+ serviceMap: Record<string, Array<string | number>>;
86
+ fallbacks?: ServiceFallbacks;
87
+ utilities?: UtilityLineItem[];
88
+ warnings?: {
89
+ utility?: Array<{
90
+ nodeId: string;
91
+ reason: string;
92
+ }>;
93
+ fallbacks?: FallbackDiagnostics[];
94
+ };
95
+ meta?: {
96
+ schema_version?: string;
97
+ workspaceId?: string;
98
+ builder?: {
99
+ commit?: string;
100
+ };
101
+ context?: SnapshotContext;
102
+ };
103
+ };
104
+
105
+ type TimeRangeEstimate = {
106
+ min_seconds?: number;
107
+ max_seconds?: number;
108
+ label?: string;
109
+ meta?: Record<string, unknown>;
110
+ };
111
+ type SpeedEstimate = {
112
+ amount?: number;
113
+ per?: "minute" | "hour" | "day" | "week" | "month";
114
+ unit?: string;
115
+ label?: string;
116
+ meta?: Record<string, unknown>;
117
+ };
118
+ type ServiceEstimates = {
119
+ start?: TimeRangeEstimate;
120
+ speed?: SpeedEstimate;
121
+ average?: TimeRangeEstimate;
122
+ meta?: Record<string, unknown>;
123
+ };
124
+ type ServiceFlag = {
125
+ enabled: boolean;
126
+ description: string;
127
+ meta?: Record<string, unknown>;
128
+ };
129
+ type IdType = string | number;
130
+ type ServiceFlags = Record<string, ServiceFlag>;
131
+ type DgpServiceCapability = {
132
+ id: IdType;
133
+ name?: string;
134
+ rate: number;
135
+ min?: number;
136
+ max?: number;
137
+ category?: string;
138
+ flags?: ServiceFlags;
139
+ estimates?: ServiceEstimates;
140
+ meta?: Record<string, unknown>;
141
+ [x: string]: any;
142
+ };
143
+ type DgpServiceMap = Record<string, DgpServiceCapability> & Record<number, DgpServiceCapability>;
144
+
145
+ type NodeRef$1 = {
146
+ kind: "tag";
147
+ id: string;
148
+ node: Tag;
149
+ } | {
150
+ kind: "field";
151
+ id: string;
152
+ node: Field;
153
+ } | {
154
+ kind: "option";
155
+ id: string;
156
+ node: FieldOption;
157
+ fieldId: string;
158
+ };
159
+ type NodeMap = Map<string, NodeRef$1>;
160
+
161
+ type ValidationCode = "root_missing" | "cycle_in_tags" | "bad_bind_reference" | "duplicate_id" | "duplicate_tag_label" | "duplicate_field_name" | "label_missing" | "duplicate_visible_label" | "bad_option_key" | "option_include_exclude_conflict" | "service_field_missing_service_id" | "user_input_field_has_service_option" | "rate_mismatch_across_base" | "utility_without_base" | "unsupported_constraint" | "constraint_contradiction" | "custom_component_missing" | "policy_violation" | "field_unbound" | "constraint_overridden" | "unsupported_constraint_option" | "custom_component_unresolvable" | "quantity_multiple_markers" | "utility_with_service_id" | "utility_missing_rate" | "utility_invalid_mode" | "fallback_bad_node" | "fallback_unknown_service" | "fallback_cycle" | "fallback_no_primary" | "fallback_rate_violation" | "fallback_constraint_mismatch" | "fallback_no_tag_context";
162
+ type ValidationError = {
163
+ code: ValidationCode;
164
+ message: string;
165
+ severity: "error" | "warning" | "info";
166
+ nodeId?: string;
167
+ details?: Record<string, unknown> & {
168
+ affectedIds?: string[];
169
+ };
170
+ };
171
+ type ServiceWhereOp = "eq" | "neq" | "in" | "nin" | "exists" | "truthy" | "falsy" | "sw";
172
+ /**
173
+ * Host-extensible service filter clause.
174
+ * `path` should usually be "service.<prop>" or "service.meta.<prop>" etc.
175
+ */
176
+ type ServiceWhereClause = {
177
+ path: string;
178
+ op?: ServiceWhereOp;
179
+ value?: unknown;
180
+ };
181
+ type DynamicRule = {
182
+ id: string;
183
+ label?: string;
184
+ scope: "global" | "visible_group";
185
+ subject: "services";
186
+ /**
187
+ * Package-level filter surface:
188
+ * - role/tag/field are core to the builder schema
189
+ * - where[] allows hosts to filter against extra service properties (handler_id/platform_id/type/key/category_id/etc.)
190
+ */
191
+ filter?: {
192
+ role?: "base" | "utility" | "both";
193
+ tag_id?: string | string[];
194
+ field_id?: string | string[];
195
+ where?: ServiceWhereClause[];
196
+ };
197
+ /**
198
+ * Projection is intentionally open:
199
+ * hosts may project custom service properties.
200
+ */
201
+ projection?: "service.id" | "service.name" | "service.rate" | "service.min" | "service.max" | "service.category" | string;
202
+ op: "all_equal" | "unique" | "no_mix" | "all_true" | "any_true" | "max_count" | "min_count";
203
+ value?: number | boolean;
204
+ severity?: "error" | "warning";
205
+ message?: string;
206
+ };
207
+ type ValidatorOptions = {
208
+ serviceMap?: DgpServiceMap;
209
+ nodeMap?: NodeMap;
210
+ allowUnsafe?: boolean;
211
+ selectedOptionKeys?: string[];
212
+ globalUtilityGuard?: boolean;
213
+ policies?: DynamicRule[];
214
+ fallbackSettings?: FallbackSettings;
215
+ };
216
+ type RatePolicy = {
217
+ kind: "lte_primary";
218
+ } | {
219
+ kind: "within_pct";
220
+ pct: number;
221
+ } | {
222
+ kind: "at_least_pct_lower";
223
+ pct: number;
224
+ };
225
+ type FallbackSettings = {
226
+ /** Require fallbacks to satisfy tag constraints (dripfeed/refill/cancel) when a tag context is known. Default: true */
227
+ requireConstraintFit?: boolean;
228
+ /** Rate rule policy. Default: { kind: 'lte_primary' } i.e. candidate.rate <= primary.rate */
229
+ ratePolicy?: RatePolicy;
230
+ /** When multiple candidates remain, choose first (priority) or cheapest. Default: 'priority' */
231
+ selectionStrategy?: "priority" | "cheapest";
232
+ /** Validation mode: 'strict' → node-scoped violations reported as ValidationError; 'dev' → only collect diagnostics. Default: 'strict' */
233
+ mode?: "strict" | "dev";
234
+ };
235
+
236
+ type ServiceIdRef = number | string;
237
+ type NodeIdRef = string;
238
+ type ServiceFallback = {
239
+ /** Node-scoped fallbacks: prefer these when that node’s primary service fails */
240
+ nodes?: Record<NodeIdRef, ServiceIdRef[]>;
241
+ /** Primary→fallback list used when no node-scoped entry is present */
242
+ global?: Record<ServiceIdRef, ServiceIdRef[]>;
243
+ };
244
+ /**
245
+ * Optional service-map shape.
246
+ * Keep this loose for now so the editor can be reused by host apps.
247
+ */
248
+ type FallbackEditorServiceRecord = {
249
+ id: ServiceIdRef;
250
+ rate?: number;
251
+ service_id?: ServiceIdRef;
252
+ [key: string]: unknown;
253
+ };
254
+ type FallbackEditorServiceMap = DgpServiceMap;
255
+ type FallbackRegistrationScope = "global" | "node";
256
+ type FallbackScopeRef = {
257
+ scope: "global";
258
+ primary: ServiceIdRef;
259
+ } | {
260
+ scope: "node";
261
+ nodeId: NodeIdRef;
262
+ };
263
+ type FallbackRegistration = {
264
+ scope: FallbackRegistrationScope;
265
+ /**
266
+ * For node scope => node id
267
+ * For global scope => omitted
268
+ */
269
+ scopeId?: NodeIdRef;
270
+ /**
271
+ * The primary DGP service this registration belongs to.
272
+ * For global scope, this is the global key.
273
+ * For node scope, this is resolved from ServiceProps/snapshot context.
274
+ */
275
+ primary: ServiceIdRef;
276
+ /** Registered fallback services */
277
+ services: ServiceIdRef[];
278
+ };
279
+ type FallbackCheckReason = "duplicate" | "self_reference" | "unknown_primary" | "unknown_candidate" | "missing_snapshot" | "node_scope_not_supported" | "node_primary_unresolved" | "ambiguous_context" | "invalid_candidate" | "unknown_service" | "no_primary" | "rate_violation" | "constraint_mismatch" | "cycle" | "no_tag_context" | "missing_service_props" | "node_not_found";
280
+ type FallbackCandidateCheck = {
281
+ candidate: ServiceIdRef;
282
+ ok: boolean;
283
+ reasons: FallbackCheckReason[];
284
+ };
285
+ type FallbackCheckResult = {
286
+ context: FallbackScopeRef;
287
+ /**
288
+ * Resolved primary when known.
289
+ * For global scope this should normally equal context.primary.
290
+ */
291
+ primary?: ServiceIdRef;
292
+ allowed: ServiceIdRef[];
293
+ rejected: FallbackCandidateCheck[];
294
+ warnings: FallbackCheckReason[];
295
+ };
296
+ type FallbackEditorState = {
297
+ original: ServiceFallback;
298
+ current: ServiceFallback;
299
+ changed: boolean;
300
+ };
301
+ type FallbackEditorOptions = {
302
+ /**
303
+ * The editable payload.
304
+ * The editor clones this and never mutates the caller’s object directly.
305
+ */
306
+ fallbacks?: ServiceFallback;
307
+ /**
308
+ * Optional read-only source used to resolve node→service ownership
309
+ * and validate node-scoped registrations.
310
+ */
311
+ props?: ServiceProps;
312
+ /**
313
+ * Optional runtime context enhancer.
314
+ * Useful for ambiguous node contexts / diagnostics.
315
+ */
316
+ snapshot?: OrderSnapshot;
317
+ /**
318
+ * Optional service map used for rate / existence validation.
319
+ */
320
+ services?: FallbackEditorServiceMap;
321
+ /**
322
+ * Optional fallback policy.
323
+ */
324
+ settings?: FallbackSettings;
325
+ };
326
+ type FallbackMutationOptions = {
327
+ /**
328
+ * When true, reject candidates failing validation.
329
+ * When false, keep structurally valid values and return warnings.
330
+ */
331
+ strict?: boolean;
332
+ /**
333
+ * Optional insert position for add/addMany.
334
+ * Omit to append.
335
+ */
336
+ index?: number;
337
+ };
338
+ interface FallbackEditor {
339
+ /** Returns original + current editable state */
340
+ state(): FallbackEditorState;
341
+ /** Returns the current editable fallback payload */
342
+ value(): ServiceFallback;
343
+ /** Restores current back to original */
344
+ reset(): FallbackEditorState;
345
+ /**
346
+ * Returns all registrations belonging to a given primary DGP service.
347
+ *
348
+ * With ServiceProps:
349
+ * - includes global registrations
350
+ * - includes node registrations whose node resolves to this primary
351
+ *
352
+ * Without ServiceProps:
353
+ * - global registrations only
354
+ */
355
+ get(serviceId: ServiceIdRef): FallbackRegistration[];
356
+ /**
357
+ * Direct/raw scope lookup.
358
+ * - global => current.global[primary] ?? []
359
+ * - node => current.nodes[nodeId] ?? []
360
+ */
361
+ getScope(context: FallbackScopeRef): ServiceIdRef[];
362
+ /**
363
+ * Pure validation/preview.
364
+ * If candidates omitted, validates the currently stored scope value.
365
+ */
366
+ check(context: FallbackScopeRef, candidates?: ServiceIdRef[]): FallbackCheckResult;
367
+ /** Adds one candidate to an exact scope */
368
+ add(context: FallbackScopeRef, candidate: ServiceIdRef, options?: FallbackMutationOptions): FallbackEditorState;
369
+ /** Adds many candidates to an exact scope */
370
+ addMany(context: FallbackScopeRef, candidates: ServiceIdRef[], options?: FallbackMutationOptions): FallbackEditorState;
371
+ /** Removes one candidate from an exact scope */
372
+ remove(context: FallbackScopeRef, candidate: ServiceIdRef): FallbackEditorState;
373
+ /** Replaces the exact scope value */
374
+ replace(context: FallbackScopeRef, candidates: ServiceIdRef[], options?: FallbackMutationOptions): FallbackEditorState;
375
+ /** Clears one exact scope value */
376
+ clear(context: FallbackScopeRef): FallbackEditorState;
377
+ }
378
+ declare function createFallbackEditor(options?: FallbackEditorOptions): FallbackEditor;
379
+
5
380
  type PricingRole = "base" | "utility";
6
381
  type FieldType = "custom" | (string & {});
7
382
  /** ── Marker types (live inside meta; non-breaking) ───────────────────── */
@@ -214,14 +589,6 @@ type ServiceProps = {
214
589
  name?: string;
215
590
  notices?: ServicePropsNotice[];
216
591
  };
217
- type ServiceIdRef = number | string;
218
- type NodeIdRef = string;
219
- type ServiceFallback = {
220
- /** Node-scoped fallbacks: prefer these when that node’s primary service fails */
221
- nodes?: Record<NodeIdRef, ServiceIdRef[]>;
222
- /** Primary→fallback list used when no node-scoped entry is present */
223
- global?: Record<ServiceIdRef, ServiceIdRef[]>;
224
- };
225
592
  type NoticeType = "public" | "private";
226
593
  type NoticeSeverity = "info" | "warning" | "error";
227
594
  /**
@@ -449,137 +816,6 @@ type EditorSnapshot = {
449
816
  meta?: Record<string, unknown>;
450
817
  };
451
818
 
452
- type TimeRangeEstimate = {
453
- min_seconds?: number;
454
- max_seconds?: number;
455
- label?: string;
456
- meta?: Record<string, unknown>;
457
- };
458
- type SpeedEstimate = {
459
- amount?: number;
460
- per?: "minute" | "hour" | "day" | "week" | "month";
461
- unit?: string;
462
- label?: string;
463
- meta?: Record<string, unknown>;
464
- };
465
- type ServiceEstimates = {
466
- start?: TimeRangeEstimate;
467
- speed?: SpeedEstimate;
468
- average?: TimeRangeEstimate;
469
- meta?: Record<string, unknown>;
470
- };
471
- type ServiceFlag = {
472
- enabled: boolean;
473
- description: string;
474
- meta?: Record<string, unknown>;
475
- };
476
- type IdType = string | number;
477
- type ServiceFlags = Record<string, ServiceFlag>;
478
- type DgpServiceCapability = {
479
- id: IdType;
480
- name?: string;
481
- rate: number;
482
- min?: number;
483
- max?: number;
484
- category?: string;
485
- flags?: ServiceFlags;
486
- estimates?: ServiceEstimates;
487
- meta?: Record<string, unknown>;
488
- [x: string]: any;
489
- };
490
- type DgpServiceMap = Record<string, DgpServiceCapability> & Record<number, DgpServiceCapability>;
491
-
492
- type NodeRef$1 = {
493
- kind: "tag";
494
- id: string;
495
- node: Tag;
496
- } | {
497
- kind: "field";
498
- id: string;
499
- node: Field;
500
- } | {
501
- kind: "option";
502
- id: string;
503
- node: FieldOption;
504
- fieldId: string;
505
- };
506
- type NodeMap = Map<string, NodeRef$1>;
507
-
508
- type ValidationCode = "root_missing" | "cycle_in_tags" | "bad_bind_reference" | "duplicate_id" | "duplicate_tag_label" | "duplicate_field_name" | "label_missing" | "duplicate_visible_label" | "bad_option_key" | "option_include_exclude_conflict" | "service_field_missing_service_id" | "user_input_field_has_service_option" | "rate_mismatch_across_base" | "utility_without_base" | "unsupported_constraint" | "constraint_contradiction" | "custom_component_missing" | "policy_violation" | "field_unbound" | "constraint_overridden" | "unsupported_constraint_option" | "custom_component_unresolvable" | "quantity_multiple_markers" | "utility_with_service_id" | "utility_missing_rate" | "utility_invalid_mode" | "fallback_bad_node" | "fallback_unknown_service" | "fallback_cycle" | "fallback_no_primary" | "fallback_rate_violation" | "fallback_constraint_mismatch" | "fallback_no_tag_context";
509
- type ValidationError = {
510
- code: ValidationCode;
511
- message: string;
512
- severity: "error" | "warning" | "info";
513
- nodeId?: string;
514
- details?: Record<string, unknown> & {
515
- affectedIds?: string[];
516
- };
517
- };
518
- type ServiceWhereOp = "eq" | "neq" | "in" | "nin" | "exists" | "truthy" | "falsy" | "sw";
519
- /**
520
- * Host-extensible service filter clause.
521
- * `path` should usually be "service.<prop>" or "service.meta.<prop>" etc.
522
- */
523
- type ServiceWhereClause = {
524
- path: string;
525
- op?: ServiceWhereOp;
526
- value?: unknown;
527
- };
528
- type DynamicRule = {
529
- id: string;
530
- label?: string;
531
- scope: "global" | "visible_group";
532
- subject: "services";
533
- /**
534
- * Package-level filter surface:
535
- * - role/tag/field are core to the builder schema
536
- * - where[] allows hosts to filter against extra service properties (handler_id/platform_id/type/key/category_id/etc.)
537
- */
538
- filter?: {
539
- role?: "base" | "utility" | "both";
540
- tag_id?: string | string[];
541
- field_id?: string | string[];
542
- where?: ServiceWhereClause[];
543
- };
544
- /**
545
- * Projection is intentionally open:
546
- * hosts may project custom service properties.
547
- */
548
- projection?: "service.id" | "service.name" | "service.rate" | "service.min" | "service.max" | "service.category" | string;
549
- op: "all_equal" | "unique" | "no_mix" | "all_true" | "any_true" | "max_count" | "min_count";
550
- value?: number | boolean;
551
- severity?: "error" | "warning";
552
- message?: string;
553
- };
554
- type ValidatorOptions = {
555
- serviceMap?: DgpServiceMap;
556
- nodeMap?: NodeMap;
557
- allowUnsafe?: boolean;
558
- selectedOptionKeys?: string[];
559
- globalUtilityGuard?: boolean;
560
- policies?: DynamicRule[];
561
- fallbackSettings?: FallbackSettings;
562
- };
563
- type RatePolicy = {
564
- kind: "lte_primary";
565
- } | {
566
- kind: "within_pct";
567
- pct: number;
568
- } | {
569
- kind: "at_least_pct_lower";
570
- pct: number;
571
- };
572
- type FallbackSettings = {
573
- /** Require fallbacks to satisfy tag constraints (dripfeed/refill/cancel) when a tag context is known. Default: true */
574
- requireConstraintFit?: boolean;
575
- /** Rate rule policy. Default: { kind: 'lte_primary' } i.e. candidate.rate <= primary.rate */
576
- ratePolicy?: RatePolicy;
577
- /** When multiple candidates remain, choose first (priority) or cheapest. Default: 'priority' */
578
- selectionStrategy?: "priority" | "cheapest";
579
- /** Validation mode: 'strict' → node-scoped violations reported as ValidationError; 'dev' → only collect diagnostics. Default: 'strict' */
580
- mode?: "strict" | "dev";
581
- };
582
-
583
819
  /** Options you can set on the builder (used for validation/visibility) */
584
820
  type BuilderOptions = Omit<ValidatorOptions, "serviceMap"> & {
585
821
  serviceMap?: DgpServiceMap;
@@ -628,112 +864,6 @@ interface Builder {
628
864
  getNodeMap(): NodeMap;
629
865
  }
630
866
 
631
- interface ButtonValue {
632
- id: string;
633
- value: string | number;
634
- service_id?: number;
635
- pricing_role?: "base" | "utility";
636
- meta?: Record<string, unknown> & UtilityMark & WithQuantityDefault;
637
- }
638
- type Scalar = string | number | boolean | ButtonValue | null;
639
- type UtilityMode = "flat" | "per_quantity" | "per_value" | "percent";
640
- type QuantityRule$1 = {
641
- valueBy: "value" | "length" | "eval";
642
- code?: string;
643
- };
644
- type UtilityLineItem = {
645
- nodeId: string;
646
- mode: UtilityMode;
647
- rate: number;
648
- inputs: {
649
- quantity: number;
650
- value?: Scalar | Scalar[];
651
- valueBy?: "value" | "length" | "eval";
652
- evalCodeUsed?: boolean;
653
- };
654
- };
655
- type ServiceFallbacks = {
656
- nodes?: Record<string, Array<string | number>>;
657
- global?: Record<string | number, Array<string | number>>;
658
- };
659
- type FallbackDiagnostics = {
660
- scope: "node" | "global";
661
- nodeId?: string;
662
- primary: string | number;
663
- candidate: string | number;
664
- reasons: Array<"rate_violation" | "constraint_mismatch" | "unknown_service" | "ambiguous_context">;
665
- };
666
- type SnapshotContext = {
667
- /** The single active tag id for this order */
668
- tag: string;
669
- /** Effective (post-propagation) constraints on that tag */
670
- constraints: Partial<Record<"refill" | "cancel" | "dripfeed", boolean>>;
671
- /**
672
- * Per-node evaluation context:
673
- * - For the active tag node itself: the same tag id.
674
- * - For an option node: parent's field.bind_id must include this tag to be applicable; otherwise null.
675
- * - For a field node (optional to include later): same rule as option, derived from field.bind_id.
676
- */
677
- nodeContexts: Record<string, string | null>;
678
- /** Client pruning policy used (so server can mirror/compare). */
679
- policy: {
680
- ratePolicy: {
681
- kind: "lte_primary" | "none";
682
- thresholdPct?: number;
683
- };
684
- requireConstraintFit: boolean;
685
- };
686
- };
687
- type OrderSnapshot = {
688
- version: "1";
689
- mode: "prod" | "dev";
690
- builtAt: string;
691
- selection: {
692
- tag: string;
693
- buttons: string[];
694
- fields: Array<{
695
- id: string;
696
- type: string;
697
- selectedOptions?: string[];
698
- }>;
699
- };
700
- inputs: {
701
- form: Record<string, Scalar | Scalar[]>;
702
- selections: Record<string, string[]>;
703
- };
704
- quantity: number;
705
- quantitySource: {
706
- kind: "field" | "tag" | "option" | "default";
707
- id?: string;
708
- rule?: QuantityRule$1;
709
- defaultedFromHost?: boolean;
710
- };
711
- min: number;
712
- max: number;
713
- services: Array<string | number>;
714
- serviceMap: Record<string, Array<string | number>>;
715
- fallbacks?: {
716
- nodes?: Record<string, Array<string | number>>;
717
- global?: Record<string | number, Array<string | number>>;
718
- };
719
- utilities?: UtilityLineItem[];
720
- warnings?: {
721
- utility?: Array<{
722
- nodeId: string;
723
- reason: string;
724
- }>;
725
- fallbacks?: FallbackDiagnostics[];
726
- };
727
- meta?: {
728
- schema_version?: string;
729
- workspaceId?: string;
730
- builder?: {
731
- commit?: string;
732
- };
733
- context?: SnapshotContext;
734
- };
735
- };
736
-
737
867
  type Env = "client" | "workspace";
738
868
  type VisibleGroup = {
739
869
  tagId?: string;
@@ -1852,4 +1982,4 @@ declare function useOrderFlow(): UseOrderFlowReturn;
1852
1982
  */
1853
1983
  declare function registerEntries(registry: Registry): void;
1854
1984
 
1855
- export { type Adapter, type AdapterCtx, type AdminPolicies, type BaseFieldUI, type ButtonValue, CanvasAPI, type CanvasEvents, type CanvasOptions, type CanvasState, type Command, type CommentAnchor, type CommentId, type CommentMessage, type CommentNode, type CommentThread, type ConnectKind, type ConstraintKey, type DgpServiceCapability, type DgpServiceMap, type DraftWire, type DynamicRule, type EdgeKind, type EdgeRoute, type EdgeView, type EditorEvents, type EditorOptions, type EditorSnapshot, EventBus, type EventMap, type FallbackDiagnostics, type FallbackSettings, type Field, type FieldOption, type FieldType, type FieldWithTypedDefaults, type FlagKey, type FlowNode, type FormApi, FormProvider, type FormProviderProps, type FormSnapshot, type GraphEdge, type GraphNode, type GraphSnapshot, type IdType, type InputDescriptor, type InputKind, type InputVariant, type InputWrapperProps, type LayoutState, type NodeIdRef, type NodeKind, type NodePos, type NodePositions, type NodeView, type NoticeKind, type NoticeSeverity, type NoticeTarget, type NoticeType, OrderFlowProvider, type OrderSnapshot, type PricingRole, Provider, type QuantityMark, type QuantityRule$1 as QuantityRule, type RatePolicy, type Registry, type Scalar, type ServiceEstimates, type ServiceFallback, type ServiceFallbacks, type ServiceFlag, type ServiceFlags, type ServiceIdRef, type ServiceProps, type ServicePropsNotice, type ServiceWhereClause, type ServiceWhereOp, type SnapshotContext, type SpeedEstimate, type Tag, type ThreadId, type TimeRangeEstimate, type Ui, type UiAnyOf, type UiArray, type UiBoolean, type UiNumber, type UiObject, type UiString, type UiValue, type UtilityLineItem, type UtilityMark, type UtilityMode, type ValidationCode, type ValidationError, type ValidatorOptions, type Viewport, type WithQuantityDefault, Wrapper, createInputRegistry, registerEntries, resolveInputDescriptor, useFormApi, useInputs, useOptionalFormApi, useOrderFlow, useOrderFlowContext };
1985
+ export { type Adapter, type AdapterCtx, type AdminPolicies, type BaseFieldUI, type ButtonValue, CanvasAPI, type CanvasEvents, type CanvasOptions, type CanvasState, type Command, type CommentAnchor, type CommentId, type CommentMessage, type CommentNode, type CommentThread, type ConnectKind, type ConstraintKey, type DgpServiceCapability, type DgpServiceMap, type DraftWire, type DynamicRule, type EdgeKind, type EdgeRoute, type EdgeView, type EditorEvents, type EditorOptions, type EditorSnapshot, EventBus, type EventMap, type FallbackCandidateCheck, type FallbackCheckReason, type FallbackCheckResult, type FallbackDiagnostics, type FallbackEditor, type FallbackEditorOptions, type FallbackEditorServiceMap, type FallbackEditorServiceRecord, type FallbackEditorState, type FallbackMutationOptions, type FallbackRegistration, type FallbackRegistrationScope, type FallbackScopeRef, type FallbackSettings, type Field, type FieldOption, type FieldType, type FieldWithTypedDefaults, type FlagKey, type FlowNode, type FormApi, FormProvider, type FormProviderProps, type FormSnapshot, type GraphEdge, type GraphNode, type GraphSnapshot, type IdType, type InputDescriptor, type InputKind, type InputVariant, type InputWrapperProps, type LayoutState, type NodeIdRef, type NodeKind, type NodePos, type NodePositions, type NodeView, type NoticeKind, type NoticeSeverity, type NoticeTarget, type NoticeType, OrderFlowProvider, type OrderSnapshot, type PricingRole, Provider, type QuantityMark, type QuantityRule$1 as QuantityRule, type RatePolicy, type Registry, type Scalar, type ServiceEstimates, type ServiceFallback, type ServiceFallbacks, type ServiceFlag, type ServiceFlags, type ServiceIdRef, type ServiceProps, type ServicePropsNotice, type ServiceWhereClause, type ServiceWhereOp, type SnapshotContext, type SpeedEstimate, type Tag, type ThreadId, type TimeRangeEstimate, type Ui, type UiAnyOf, type UiArray, type UiBoolean, type UiNumber, type UiObject, type UiString, type UiValue, type UtilityLineItem, type UtilityMark, type UtilityMode, type ValidationCode, type ValidationError, type ValidatorOptions, type Viewport, type WithQuantityDefault, Wrapper, createFallbackEditor, createInputRegistry, registerEntries, resolveInputDescriptor, useFormApi, useInputs, useOptionalFormApi, useOrderFlow, useOrderFlowContext };