@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/README.md CHANGED
@@ -580,9 +580,9 @@ Values are bounded to identifier-shaped compact tokens, with
580
580
  specialized BCP-47 validation for `locale` and IANA validation for
581
581
  `timezone`.
582
582
 
583
- **Open pattern** (4 canonical suffixes): keys matching
584
- `^[a-z][A-Za-z0-9]*(Class|Count|Kind|Role)$` are admitted alongside
585
- the stable core. Value shapes are suffix-routed:
583
+ **Open pattern** (5 canonical suffixes): keys matching
584
+ `^[a-z][A-Za-z0-9]*(Class|Count|Kind|Role|Holds)$` are admitted
585
+ alongside the stable core. Value shapes are suffix-routed:
586
586
 
587
587
  | Suffix | Value shape | Max length | Casing convention | Examples |
588
588
  |---|---|---|---|---|
@@ -590,6 +590,7 @@ the stable core. Value shapes are suffix-routed:
590
590
  | `*Count` | non-negative integer string | 16 | digits only (no `-`, `.`, or letters) | `participantCount="2"`, `attemptCount="3"` |
591
591
  | `*Kind` | identifier-shaped compact token | 80 | lowerCamel or `UPPERCASE-CONST` | `notificationKind=transactional` |
592
592
  | `*Role` | identifier-shaped compact token | 80 | lowercase-kebab | `actorRole=operator` |
593
+ | `*Holds` | boolean-literal string | 5 | `"true"` / `"false"` only | `timezonePreservedHolds="false"` (see [Boolean relations](#boolean-relations-holds)) |
593
594
 
594
595
  Value casing is preserved verbatim; normalize at the call site so
595
596
  cross-trace comparisons collapse to the same identity. Non-digit
@@ -727,6 +728,46 @@ Pseudonymize identifiers with **`hashId`** (HMAC-SHA256, fixed-shape
727
728
  the Node-only `@glasstrace/sdk/node` subpath because it uses
728
729
  `node:crypto`. At most 16 scalars are recorded per operation.
729
730
 
731
+ ### Boolean relations (`*Holds`)
732
+
733
+ When the decisive evidence is a *relationship* between values rather than
734
+ the values themselves, emit it as a boolean **relation** on the
735
+ categorical field channel. `recordSideEffect()` accepts a `relations` map
736
+ of `boolean`s keyed by camelCase names ending in `Holds`; values are
737
+ coerced to `"true"`/`"false"`:
738
+
739
+ > **Availability:** the SDK emits `*Holds` relations now, but the Glasstrace
740
+ > backend admits them only once a coordinated release lands; until then a
741
+ > `*Holds` field is dropped at ingestion (like any unrecognized key) and is
742
+ > not yet surfaced in traces. Capture is also gated by the account
743
+ > `sideEffectEvidence` flag.
744
+
745
+ ```ts
746
+ import { recordSideEffect, invariant, isNullInvariant } from "@glasstrace/sdk";
747
+
748
+ recordSideEffect({
749
+ kind: "calendar_link",
750
+ operation: "invite.create",
751
+ relations: {
752
+ // Did the emitted duration match what was declared?
753
+ durationMatchesHolds: invariant(emittedMinutes, "eq", declaredMinutes),
754
+ // Was the timezone preserved (not silently dropped)?
755
+ timezonePreservedHolds: invariant(emittedTz, "eq", declaredTz),
756
+ recipientMissingHolds: isNullInvariant(recipient),
757
+ },
758
+ });
759
+ ```
760
+
761
+ `invariant(left, op, right)` evaluates one of `eq` / `neq` / `lt` / `lte`
762
+ / `gt` / `gte` and returns the boolean; `isNullInvariant(value)` is the
763
+ unary `null`/`undefined` check. Both are pure and edge-safe (root barrel).
764
+
765
+ A relation key not ending in `Holds`, a non-boolean value, or a key
766
+ already attached by `fields` (a same-channel collision — `fields` takes
767
+ precedence) is dropped and recorded only as an integer omission count.
768
+ Relations count against the same product-side per-operation field budget
769
+ as `fields` (enforced at projection).
770
+
730
771
  ## Source maps
731
772
 
732
773
  Glasstrace uploads server-side source maps at build time and resolves