@glasstrace/sdk 1.16.0 → 1.17.0

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.
Files changed (54) hide show
  1. package/README.md +44 -3
  2. package/dist/async-context/index.cjs.map +1 -1
  3. package/dist/async-context/index.js +2 -2
  4. package/dist/{chunk-WOYJAG7H.js → chunk-BJOZBAP7.js} +3 -3
  5. package/dist/{chunk-AFTCLH77.js → chunk-CN5EP25B.js} +2 -2
  6. package/dist/{chunk-KM4UNN3Q.js → chunk-EVX6D2TX.js} +2 -2
  7. package/dist/{chunk-EWW3TZ52.js → chunk-F2IPBTDJ.js} +48 -10
  8. package/dist/{chunk-EWW3TZ52.js.map → chunk-F2IPBTDJ.js.map} +1 -1
  9. package/dist/{chunk-BGJKEFBN.js → chunk-M3QGJUEI.js} +2 -2
  10. package/dist/{chunk-GBVMPMVV.js → chunk-MKT54VEH.js} +2 -2
  11. package/dist/{chunk-GBVMPMVV.js.map → chunk-MKT54VEH.js.map} +1 -1
  12. package/dist/{chunk-OHSX224U.js → chunk-O7IJP2TQ.js} +2 -2
  13. package/dist/{chunk-774XIOZG.js → chunk-UOAG72NR.js} +2 -2
  14. package/dist/{chunk-T7B752NF.js → chunk-VEQX2YSQ.js} +3 -3
  15. package/dist/{chunk-DW3CZDS6.js → chunk-YKE6HJLW.js} +2 -2
  16. package/dist/cli/init.cjs +4 -4
  17. package/dist/cli/init.cjs.map +1 -1
  18. package/dist/cli/init.js +7 -7
  19. package/dist/cli/mcp-add.cjs +1 -1
  20. package/dist/cli/mcp-add.cjs.map +1 -1
  21. package/dist/cli/mcp-add.js +3 -3
  22. package/dist/cli/uninit.js +3 -3
  23. package/dist/cli/upgrade-instructions.cjs +1 -1
  24. package/dist/cli/upgrade-instructions.js +3 -3
  25. package/dist/cli/validate.cjs.map +1 -1
  26. package/dist/cli/validate.js +2 -2
  27. package/dist/edge-entry.cjs.map +1 -1
  28. package/dist/edge-entry.js +4 -4
  29. package/dist/index.cjs +71 -6
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +74 -1
  32. package/dist/index.d.ts +74 -1
  33. package/dist/index.js +30 -5
  34. package/dist/index.js.map +1 -1
  35. package/dist/middleware/index.cjs.map +1 -1
  36. package/dist/middleware/index.js +2 -2
  37. package/dist/node-entry.cjs +5 -5
  38. package/dist/node-entry.cjs.map +1 -1
  39. package/dist/node-entry.js +7 -7
  40. package/dist/node-subpath.cjs.map +1 -1
  41. package/dist/node-subpath.js +3 -3
  42. package/dist/{source-map-uploader-UJPZCUFN.js → source-map-uploader-U7SLSKIZ.js} +3 -3
  43. package/dist/trpc/index.cjs.map +1 -1
  44. package/dist/trpc/index.js +1 -1
  45. package/package.json +1 -1
  46. /package/dist/{chunk-WOYJAG7H.js.map → chunk-BJOZBAP7.js.map} +0 -0
  47. /package/dist/{chunk-AFTCLH77.js.map → chunk-CN5EP25B.js.map} +0 -0
  48. /package/dist/{chunk-KM4UNN3Q.js.map → chunk-EVX6D2TX.js.map} +0 -0
  49. /package/dist/{chunk-BGJKEFBN.js.map → chunk-M3QGJUEI.js.map} +0 -0
  50. /package/dist/{chunk-OHSX224U.js.map → chunk-O7IJP2TQ.js.map} +0 -0
  51. /package/dist/{chunk-774XIOZG.js.map → chunk-UOAG72NR.js.map} +0 -0
  52. /package/dist/{chunk-T7B752NF.js.map → chunk-VEQX2YSQ.js.map} +0 -0
  53. /package/dist/{chunk-DW3CZDS6.js.map → chunk-YKE6HJLW.js.map} +0 -0
  54. /package/dist/{source-map-uploader-UJPZCUFN.js.map → source-map-uploader-U7SLSKIZ.js.map} +0 -0
package/dist/index.d.cts CHANGED
@@ -90,6 +90,20 @@ interface RecordSideEffectInput {
90
90
  * prefix), so a categorical and a scalar facet can share a name.
91
91
  */
92
92
  scalars?: Record<string, unknown>;
93
+ /**
94
+ * Optional producer-asserted boolean relations (invariants) emitted on
95
+ * the categorical field channel. Keys must be camelCase ending in
96
+ * `Holds` (e.g. `timezonePreservedHolds`); values are real `boolean`s,
97
+ * coerced to `"true"`/`"false"` on the wire. A non-`Holds` key, a
98
+ * non-boolean value, or a key already attached by `fields` (a
99
+ * same-channel collision — `fields` wins) is dropped with the matching
100
+ * omission counter. Relations count against the same product-side
101
+ * per-operation field budget as `fields` (enforced at projection).
102
+ *
103
+ * Use {@link invariant} / {@link isNullInvariant} to compute the
104
+ * boolean from a comparison.
105
+ */
106
+ relations?: Record<string, boolean>;
93
107
  }
94
108
  /**
95
109
  * Record allowlisted side-effect evidence on the current active OTel
@@ -143,4 +157,63 @@ interface RecordSideEffectInput {
143
157
  */
144
158
  declare function recordSideEffect(input: RecordSideEffectInput): void;
145
159
 
146
- export { type RecordSideEffectInput, SideEffectOperationKind, SideEffectOperationPhase, SideEffectOperationStatus, SideEffectSemanticFieldKey, recordSideEffect };
160
+ /**
161
+ * Producer-sugar for computing boolean relations to emit as `*Holds`
162
+ * side-effect evidence.
163
+ *
164
+ * These helpers turn a comparison into the boolean a producer passes to
165
+ * `recordSideEffect({ relations: { …Holds: invariant(a, "eq", b) } })`.
166
+ * They are pure (no I/O, no Node built-ins) and edge-safe, so they live
167
+ * on the root barrel. The operator set is intentionally minimal and
168
+ * fixed — six binary comparisons plus a separate unary null check — and
169
+ * is not a general expression DSL.
170
+ */
171
+ /**
172
+ * The six supported binary comparison operators. `isNull` is **not** an
173
+ * operator here — use {@link isNullInvariant} for the unary case.
174
+ */
175
+ type InvariantOp = "eq" | "neq" | "lt" | "lte" | "gt" | "gte";
176
+ /**
177
+ * Evaluate a binary comparison invariant and return the boolean result.
178
+ *
179
+ * Both operands are constrained to the same primitive type. `eq`/`neq`
180
+ * use strict equality; the ordering operators (`lt`/`lte`/`gt`/`gte`)
181
+ * use the language relational operators (numeric for numbers/bigints,
182
+ * lexical for strings). Intended for producing a `*Holds` relation, e.g.
183
+ * `invariant(emittedDurationMinutes, "eq", declaredDurationMinutes)`.
184
+ *
185
+ * Operands should be comparable primitives. `NaN` follows IEEE-754
186
+ * (unequal to everything; all orderings `false`), so screen `NaN` before
187
+ * asserting a relation. Passing a non-primitive (e.g. a `Symbol`, or an
188
+ * object with a throwing `valueOf`) to an ordering operator throws per
189
+ * JS semantics — the type signature prevents this for typed callers.
190
+ *
191
+ * @param left - The left operand.
192
+ * @param op - One of the six {@link InvariantOp} comparisons.
193
+ * @param right - The right operand (same primitive type as `left`).
194
+ * @returns The boolean result of `left <op> right`.
195
+ *
196
+ * @example
197
+ * recordSideEffect({
198
+ * kind: "calendar_link",
199
+ * operation: "invite.create",
200
+ * relations: {
201
+ * durationMatchesHolds: invariant(emittedMinutes, "eq", declaredMinutes),
202
+ * },
203
+ * });
204
+ */
205
+ declare function invariant<T extends number | string | bigint | boolean>(left: T, op: InvariantOp, right: T): boolean;
206
+ /**
207
+ * Unary null/undefined invariant — `true` when `value` is `null` or
208
+ * `undefined`. Kept separate from {@link invariant} because nullishness
209
+ * is a unary predicate, not a binary comparison (there is no `isNull`
210
+ * operator). Use for a `*Holds` relation asserting a value's absence,
211
+ * e.g. `relations: { recipientMissingHolds: isNullInvariant(recipient) }`.
212
+ *
213
+ * @param value - The value to test.
214
+ * @returns `true` when `value` is `null` or `undefined`, else `false`
215
+ * (falsy-but-present values like `0`, `""`, `false`, `NaN` are `false`).
216
+ */
217
+ declare function isNullInvariant(value: unknown): boolean;
218
+
219
+ export { type InvariantOp, type RecordSideEffectInput, SideEffectOperationKind, SideEffectOperationPhase, SideEffectOperationStatus, SideEffectSemanticFieldKey, invariant, isNullInvariant, recordSideEffect };
package/dist/index.d.ts CHANGED
@@ -90,6 +90,20 @@ interface RecordSideEffectInput {
90
90
  * prefix), so a categorical and a scalar facet can share a name.
91
91
  */
92
92
  scalars?: Record<string, unknown>;
93
+ /**
94
+ * Optional producer-asserted boolean relations (invariants) emitted on
95
+ * the categorical field channel. Keys must be camelCase ending in
96
+ * `Holds` (e.g. `timezonePreservedHolds`); values are real `boolean`s,
97
+ * coerced to `"true"`/`"false"` on the wire. A non-`Holds` key, a
98
+ * non-boolean value, or a key already attached by `fields` (a
99
+ * same-channel collision — `fields` wins) is dropped with the matching
100
+ * omission counter. Relations count against the same product-side
101
+ * per-operation field budget as `fields` (enforced at projection).
102
+ *
103
+ * Use {@link invariant} / {@link isNullInvariant} to compute the
104
+ * boolean from a comparison.
105
+ */
106
+ relations?: Record<string, boolean>;
93
107
  }
94
108
  /**
95
109
  * Record allowlisted side-effect evidence on the current active OTel
@@ -143,4 +157,63 @@ interface RecordSideEffectInput {
143
157
  */
144
158
  declare function recordSideEffect(input: RecordSideEffectInput): void;
145
159
 
146
- export { type RecordSideEffectInput, SideEffectOperationKind, SideEffectOperationPhase, SideEffectOperationStatus, SideEffectSemanticFieldKey, recordSideEffect };
160
+ /**
161
+ * Producer-sugar for computing boolean relations to emit as `*Holds`
162
+ * side-effect evidence.
163
+ *
164
+ * These helpers turn a comparison into the boolean a producer passes to
165
+ * `recordSideEffect({ relations: { …Holds: invariant(a, "eq", b) } })`.
166
+ * They are pure (no I/O, no Node built-ins) and edge-safe, so they live
167
+ * on the root barrel. The operator set is intentionally minimal and
168
+ * fixed — six binary comparisons plus a separate unary null check — and
169
+ * is not a general expression DSL.
170
+ */
171
+ /**
172
+ * The six supported binary comparison operators. `isNull` is **not** an
173
+ * operator here — use {@link isNullInvariant} for the unary case.
174
+ */
175
+ type InvariantOp = "eq" | "neq" | "lt" | "lte" | "gt" | "gte";
176
+ /**
177
+ * Evaluate a binary comparison invariant and return the boolean result.
178
+ *
179
+ * Both operands are constrained to the same primitive type. `eq`/`neq`
180
+ * use strict equality; the ordering operators (`lt`/`lte`/`gt`/`gte`)
181
+ * use the language relational operators (numeric for numbers/bigints,
182
+ * lexical for strings). Intended for producing a `*Holds` relation, e.g.
183
+ * `invariant(emittedDurationMinutes, "eq", declaredDurationMinutes)`.
184
+ *
185
+ * Operands should be comparable primitives. `NaN` follows IEEE-754
186
+ * (unequal to everything; all orderings `false`), so screen `NaN` before
187
+ * asserting a relation. Passing a non-primitive (e.g. a `Symbol`, or an
188
+ * object with a throwing `valueOf`) to an ordering operator throws per
189
+ * JS semantics — the type signature prevents this for typed callers.
190
+ *
191
+ * @param left - The left operand.
192
+ * @param op - One of the six {@link InvariantOp} comparisons.
193
+ * @param right - The right operand (same primitive type as `left`).
194
+ * @returns The boolean result of `left <op> right`.
195
+ *
196
+ * @example
197
+ * recordSideEffect({
198
+ * kind: "calendar_link",
199
+ * operation: "invite.create",
200
+ * relations: {
201
+ * durationMatchesHolds: invariant(emittedMinutes, "eq", declaredMinutes),
202
+ * },
203
+ * });
204
+ */
205
+ declare function invariant<T extends number | string | bigint | boolean>(left: T, op: InvariantOp, right: T): boolean;
206
+ /**
207
+ * Unary null/undefined invariant — `true` when `value` is `null` or
208
+ * `undefined`. Kept separate from {@link invariant} because nullishness
209
+ * is a unary predicate, not a binary comparison (there is no `isNull`
210
+ * operator). Use for a `*Holds` relation asserting a value's absence,
211
+ * e.g. `relations: { recipientMissingHolds: isNullInvariant(recipient) }`.
212
+ *
213
+ * @param value - The value to test.
214
+ * @returns `true` when `value` is `null` or `undefined`, else `false`
215
+ * (falsy-but-present values like `0`, `""`, `false`, `NaN` are `false`).
216
+ */
217
+ declare function isNullInvariant(value: unknown): boolean;
218
+
219
+ export { type InvariantOp, type RecordSideEffectInput, SideEffectOperationKind, SideEffectOperationPhase, SideEffectOperationStatus, SideEffectSemanticFieldKey, invariant, isNullInvariant, recordSideEffect };
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  recordSideEffect,
11
11
  registerGlasstrace,
12
12
  withGlasstraceConfig
13
- } from "./chunk-EWW3TZ52.js";
13
+ } from "./chunk-F2IPBTDJ.js";
14
14
  import {
15
15
  getStatus,
16
16
  isReady,
@@ -20,7 +20,7 @@ import {
20
20
  GlasstraceSpanProcessor,
21
21
  SdkError,
22
22
  captureCorrelationId
23
- } from "./chunk-KM4UNN3Q.js";
23
+ } from "./chunk-EVX6D2TX.js";
24
24
  import "./chunk-CL3OVHPO.js";
25
25
  import "./chunk-DQ25VOKK.js";
26
26
  import "./chunk-YG3X7TUI.js";
@@ -31,7 +31,7 @@ import {
31
31
  performInit,
32
32
  saveCachedConfig,
33
33
  sendInitRequest
34
- } from "./chunk-T7B752NF.js";
34
+ } from "./chunk-VEQX2YSQ.js";
35
35
  import {
36
36
  isAnonymousMode,
37
37
  isProductionDisabled,
@@ -41,13 +41,36 @@ import {
41
41
  import {
42
42
  getOrCreateAnonKey,
43
43
  readAnonKey
44
- } from "./chunk-774XIOZG.js";
44
+ } from "./chunk-UOAG72NR.js";
45
45
  import {
46
46
  deriveSessionId,
47
47
  isSideEffectSemanticFieldKey
48
- } from "./chunk-GBVMPMVV.js";
48
+ } from "./chunk-MKT54VEH.js";
49
49
  import "./chunk-YIEXKQYP.js";
50
50
  import "./chunk-NSBPE2FW.js";
51
+
52
+ // src/side-effect/invariant.ts
53
+ function invariant(left, op, right) {
54
+ switch (op) {
55
+ case "eq":
56
+ return left === right;
57
+ case "neq":
58
+ return left !== right;
59
+ case "lt":
60
+ return left < right;
61
+ case "lte":
62
+ return left <= right;
63
+ case "gt":
64
+ return left > right;
65
+ case "gte":
66
+ return left >= right;
67
+ }
68
+ op;
69
+ return false;
70
+ }
71
+ function isNullInvariant(value) {
72
+ return value === null || value === void 0;
73
+ }
51
74
  export {
52
75
  GlasstraceExporter,
53
76
  GlasstraceSpanProcessor,
@@ -65,7 +88,9 @@ export {
65
88
  getOrCreateAnonKey,
66
89
  getOrigin,
67
90
  getStatus,
91
+ invariant,
68
92
  isAnonymousMode,
93
+ isNullInvariant,
69
94
  isProductionDisabled,
70
95
  isReady,
71
96
  isSideEffectSemanticFieldKey,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
1
+ {"version":3,"sources":["../src/side-effect/invariant.ts"],"sourcesContent":["/**\n * Producer-sugar for computing boolean relations to emit as `*Holds`\n * side-effect evidence.\n *\n * These helpers turn a comparison into the boolean a producer passes to\n * `recordSideEffect({ relations: { …Holds: invariant(a, \"eq\", b) } })`.\n * They are pure (no I/O, no Node built-ins) and edge-safe, so they live\n * on the root barrel. The operator set is intentionally minimal and\n * fixed — six binary comparisons plus a separate unary null check — and\n * is not a general expression DSL.\n */\n\n/**\n * The six supported binary comparison operators. `isNull` is **not** an\n * operator here — use {@link isNullInvariant} for the unary case.\n */\nexport type InvariantOp = \"eq\" | \"neq\" | \"lt\" | \"lte\" | \"gt\" | \"gte\";\n\n/**\n * Evaluate a binary comparison invariant and return the boolean result.\n *\n * Both operands are constrained to the same primitive type. `eq`/`neq`\n * use strict equality; the ordering operators (`lt`/`lte`/`gt`/`gte`)\n * use the language relational operators (numeric for numbers/bigints,\n * lexical for strings). Intended for producing a `*Holds` relation, e.g.\n * `invariant(emittedDurationMinutes, \"eq\", declaredDurationMinutes)`.\n *\n * Operands should be comparable primitives. `NaN` follows IEEE-754\n * (unequal to everything; all orderings `false`), so screen `NaN` before\n * asserting a relation. Passing a non-primitive (e.g. a `Symbol`, or an\n * object with a throwing `valueOf`) to an ordering operator throws per\n * JS semantics — the type signature prevents this for typed callers.\n *\n * @param left - The left operand.\n * @param op - One of the six {@link InvariantOp} comparisons.\n * @param right - The right operand (same primitive type as `left`).\n * @returns The boolean result of `left <op> right`.\n *\n * @example\n * recordSideEffect({\n * kind: \"calendar_link\",\n * operation: \"invite.create\",\n * relations: {\n * durationMatchesHolds: invariant(emittedMinutes, \"eq\", declaredMinutes),\n * },\n * });\n */\nexport function invariant<T extends number | string | bigint | boolean>(\n left: T,\n op: InvariantOp,\n right: T,\n): boolean {\n switch (op) {\n case \"eq\":\n return left === right;\n case \"neq\":\n return left !== right;\n case \"lt\":\n return left < right;\n case \"lte\":\n return left <= right;\n case \"gt\":\n return left > right;\n case \"gte\":\n return left >= right;\n }\n // For well-typed callers `op` is `never` here, so this `satisfies`\n // enforces switch exhaustiveness at compile time (adding an\n // `InvariantOp` member without a case is a type error). The `return`\n // is the runtime fallback for an untyped (JS) caller passing an\n // out-of-domain op — it yields a `boolean`, never `undefined`.\n op satisfies never;\n return false;\n}\n\n/**\n * Unary null/undefined invariant — `true` when `value` is `null` or\n * `undefined`. Kept separate from {@link invariant} because nullishness\n * is a unary predicate, not a binary comparison (there is no `isNull`\n * operator). Use for a `*Holds` relation asserting a value's absence,\n * e.g. `relations: { recipientMissingHolds: isNullInvariant(recipient) }`.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is `null` or `undefined`, else `false`\n * (falsy-but-present values like `0`, `\"\"`, `false`, `NaN` are `false`).\n */\nexport function isNullInvariant(value: unknown): boolean {\n return value === null || value === undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+CO,SAAS,UACd,MACA,IACA,OACS;AACT,UAAQ,IAAI;AAAA,IACV,KAAK;AACH,aAAO,SAAS;AAAA,IAClB,KAAK;AACH,aAAO,SAAS;AAAA,IAClB,KAAK;AACH,aAAO,OAAO;AAAA,IAChB,KAAK;AACH,aAAO,QAAQ;AAAA,IACjB,KAAK;AACH,aAAO,OAAO;AAAA,IAChB,KAAK;AACH,aAAO,QAAQ;AAAA,EACnB;AAMA;AACA,SAAO;AACT;AAaO,SAAS,gBAAgB,OAAyB;AACvD,SAAO,UAAU,QAAQ,UAAU;AACrC;","names":[]}