@rasputin-ai/core 0.5.0-alpha.1 → 0.5.0-alpha.11

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 (32) hide show
  1. package/dist/create-client/is-client-enabled.d.ts.map +1 -1
  2. package/dist/create-ingest-event/runtime-execution-state-types.d.ts +43 -6
  3. package/dist/create-ingest-event/runtime-execution-state-types.d.ts.map +1 -1
  4. package/dist/derivation/canonical-json.d.ts +3 -0
  5. package/dist/derivation/canonical-json.d.ts.map +1 -0
  6. package/dist/derivation/captured-value-markers.d.ts +5 -0
  7. package/dist/derivation/captured-value-markers.d.ts.map +1 -0
  8. package/dist/derivation/evaluate-derivation-plan.d.ts +53 -0
  9. package/dist/derivation/evaluate-derivation-plan.d.ts.map +1 -0
  10. package/dist/derivation/hash-instrumentation-manifest.d.ts +7 -0
  11. package/dist/derivation/hash-instrumentation-manifest.d.ts.map +1 -0
  12. package/dist/derivation/rasputin-wire-tag.d.ts +32 -0
  13. package/dist/derivation/rasputin-wire-tag.d.ts.map +1 -0
  14. package/dist/derivation/sha256.d.ts +3 -0
  15. package/dist/derivation/sha256.d.ts.map +1 -0
  16. package/dist/derivation/wire-values-equal.d.ts +3 -0
  17. package/dist/derivation/wire-values-equal.d.ts.map +1 -0
  18. package/dist/index.d.ts +6 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +1227 -70
  21. package/dist/instrumentation-manifest/derivation-plan-types.d.ts +142 -0
  22. package/dist/instrumentation-manifest/derivation-plan-types.d.ts.map +1 -0
  23. package/dist/instrumentation-manifest/instrumentation-manifest-types.d.ts +5 -1
  24. package/dist/instrumentation-manifest/instrumentation-manifest-types.d.ts.map +1 -1
  25. package/dist/sdk-meta.d.ts +1 -1
  26. package/dist/sdk-meta.d.ts.map +1 -1
  27. package/dist/transport/create-transport.d.ts.map +1 -1
  28. package/dist/transport/send-batch.d.ts +13 -1
  29. package/dist/transport/send-batch.d.ts.map +1 -1
  30. package/dist/transport/transport-types.d.ts +23 -0
  31. package/dist/transport/transport-types.d.ts.map +1 -1
  32. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -659,7 +659,7 @@ var resolveSourceMaps = async (frames) => {
659
659
 
660
660
  // src/sdk-meta.ts
661
661
  var SDK_NAME = "@rasputin-ai/core";
662
- var SDK_VERSION = "0.5.0-alpha.1";
662
+ var SDK_VERSION = "0.5.0-alpha.11";
663
663
 
664
664
  // src/suppression/identity-needs-message-template.ts
665
665
  var identityNeedsMessageTemplate = (type, code) => {
@@ -979,6 +979,21 @@ var sendBatch = async (options) => {
979
979
  if (options.sdkVersion) payload.sdk_version = options.sdkVersion;
980
980
  if (options.sdkName) payload.sdk_name = options.sdkName;
981
981
  if (options.idempotencyKey) payload.idempotency_key = options.idempotencyKey;
982
+ let attempts = 0;
983
+ let networkErrors = 0;
984
+ let rateLimitedResponses = 0;
985
+ let serverErrorResponses = 0;
986
+ const result = (outcome, failureKind = null, statusCode = null) => ({
987
+ outcome,
988
+ attempts,
989
+ retries: Math.max(0, attempts - 1),
990
+ networkErrors,
991
+ rateLimitedResponses,
992
+ serverErrorResponses,
993
+ aborted: failureKind === "aborted",
994
+ failureKind,
995
+ statusCode
996
+ });
982
997
  const json = JSON.stringify(payload);
983
998
  const headers = {
984
999
  Authorization: `Bearer ${options.projectApiKey}`,
@@ -994,31 +1009,38 @@ var sendBatch = async (options) => {
994
1009
  headers["Content-Encoding"] = "gzip";
995
1010
  }
996
1011
  for (let attempt = 0; attempt <= options.maxRetries; attempt++) {
997
- if (options.signal?.aborted) return "failed";
1012
+ if (options.signal?.aborted) return result("failed", "aborted");
998
1013
  try {
1014
+ attempts++;
999
1015
  const response = await options.fetch(options.ingestUrl, {
1000
1016
  method: "POST",
1001
1017
  headers,
1002
1018
  body,
1003
1019
  signal: options.signal
1004
1020
  });
1005
- if (response.ok) return "ok";
1021
+ if (response.ok) return result("ok");
1006
1022
  if (response.status === 429) {
1007
- if (attempt === options.maxRetries) return "failed";
1023
+ rateLimitedResponses++;
1024
+ if (attempt === options.maxRetries)
1025
+ return result("failed", "rate_limited", response.status);
1008
1026
  const wait = retryAfterMs(response) ?? backoffMs(attempt);
1009
1027
  await sleep(wait, options.signal);
1010
1028
  continue;
1011
1029
  }
1012
- if (response.status >= 400 && response.status < 500) return "dropped";
1013
- if (attempt === options.maxRetries) return "failed";
1030
+ if (response.status >= 400 && response.status < 500) {
1031
+ return result("dropped", "non_retryable_http", response.status);
1032
+ }
1033
+ serverErrorResponses++;
1034
+ if (attempt === options.maxRetries) return result("failed", "server_error", response.status);
1014
1035
  await sleep(backoffMs(attempt), options.signal);
1015
1036
  } catch {
1016
- if (options.signal?.aborted) return "failed";
1017
- if (attempt === options.maxRetries) return "failed";
1037
+ if (options.signal?.aborted) return result("failed", "aborted");
1038
+ networkErrors++;
1039
+ if (attempt === options.maxRetries) return result("failed", "network_error");
1018
1040
  await sleep(backoffMs(attempt), options.signal);
1019
1041
  }
1020
1042
  }
1021
- return "failed";
1043
+ return result("failed", options.signal?.aborted ? "aborted" : "network_error");
1022
1044
  };
1023
1045
 
1024
1046
  // src/transport/transport-queue.ts
@@ -1112,6 +1134,20 @@ var createTransport = (options) => {
1112
1134
  let closed = false;
1113
1135
  let shuttingDown = false;
1114
1136
  let retryBatch = null;
1137
+ let flushesStarted = 0;
1138
+ let flushesJoined = 0;
1139
+ let sendAttempts = 0;
1140
+ let sendRetries = 0;
1141
+ let batchReplays = 0;
1142
+ let batchesSucceeded = 0;
1143
+ let batchesDropped = 0;
1144
+ let batchesFailed = 0;
1145
+ let flushTimeouts = 0;
1146
+ let networkErrors = 0;
1147
+ let rateLimitedResponses = 0;
1148
+ let serverErrorResponses = 0;
1149
+ let lastFailureKind = null;
1150
+ let lastFailureStatusCode = null;
1115
1151
  const schedule = () => {
1116
1152
  if (timer || !enabled || closed) return;
1117
1153
  timer = setInterval(() => {
@@ -1133,70 +1169,94 @@ var createTransport = (options) => {
1133
1169
  return item.summary;
1134
1170
  }
1135
1171
  };
1172
+ const performFlush = async (timeoutMs) => {
1173
+ const controller = new AbortController();
1174
+ const timeout = timeoutMs > 0 ? setTimeout(() => controller.abort(), timeoutMs) : void 0;
1175
+ try {
1176
+ while (queue.size() > 0 || retryBatch) {
1177
+ if (controller.signal.aborted) break;
1178
+ const replaying = retryBatch !== null;
1179
+ const batch = retryBatch?.items ?? queue.drain(batchSize);
1180
+ const idempotencyKey = retryBatch?.idempotencyKey ?? crypto.randomUUID();
1181
+ retryBatch = null;
1182
+ if (batch.length === 0) break;
1183
+ if (replaying) batchReplays++;
1184
+ const events = [];
1185
+ const summaries = [];
1186
+ for (const item of batch) {
1187
+ if (item.kind === "summary") {
1188
+ summaries.push(await prepareSummary(item));
1189
+ continue;
1190
+ }
1191
+ if (options.prepareEvent && item.rawFrames.length > 0) {
1192
+ try {
1193
+ events.push(
1194
+ await options.prepareEvent({
1195
+ event: item.event,
1196
+ rawFrames: item.rawFrames
1197
+ })
1198
+ );
1199
+ } catch {
1200
+ events.push(item.event);
1201
+ }
1202
+ } else {
1203
+ events.push(item.event);
1204
+ }
1205
+ }
1206
+ const result = await sendBatch({
1207
+ ingestUrl: options.ingestUrl,
1208
+ projectApiKey: options.projectApiKey,
1209
+ events,
1210
+ summaries,
1211
+ idempotencyKey,
1212
+ sdkVersion: options.sdkVersion,
1213
+ sdkName: options.sdkName,
1214
+ gzipThresholdBytes,
1215
+ maxRetries,
1216
+ fetch: fetchFn,
1217
+ signal: controller.signal
1218
+ });
1219
+ sendAttempts += result.attempts;
1220
+ sendRetries += result.retries;
1221
+ networkErrors += result.networkErrors;
1222
+ rateLimitedResponses += result.rateLimitedResponses;
1223
+ serverErrorResponses += result.serverErrorResponses;
1224
+ if (result.aborted) flushTimeouts++;
1225
+ if (result.outcome === "ok") batchesSucceeded++;
1226
+ else {
1227
+ lastFailureKind = result.failureKind;
1228
+ lastFailureStatusCode = result.statusCode;
1229
+ if (result.outcome === "dropped") batchesDropped++;
1230
+ else batchesFailed++;
1231
+ }
1232
+ if (result.outcome === "failed") {
1233
+ retryBatch = { items: batch, idempotencyKey };
1234
+ break;
1235
+ }
1236
+ }
1237
+ } finally {
1238
+ if (timeout) clearTimeout(timeout);
1239
+ if (queue.size() === 0 && !retryBatch) stopTimer();
1240
+ }
1241
+ };
1136
1242
  const flush = async (timeoutMs = 1e4) => {
1137
1243
  if (!enabled || closed) {
1138
1244
  queue.clear();
1139
1245
  retryBatch = null;
1140
1246
  return;
1141
1247
  }
1142
- if (flushing) return flushing;
1143
- flushing = (async () => {
1144
- const controller = new AbortController();
1145
- const timeout = timeoutMs > 0 ? setTimeout(() => controller.abort(), timeoutMs) : void 0;
1146
- try {
1147
- while (queue.size() > 0 || retryBatch) {
1148
- if (controller.signal.aborted) break;
1149
- const batch = retryBatch?.items ?? queue.drain(batchSize);
1150
- const idempotencyKey = retryBatch?.idempotencyKey ?? crypto.randomUUID();
1151
- retryBatch = null;
1152
- if (batch.length === 0) break;
1153
- const events = [];
1154
- const summaries = [];
1155
- for (const item of batch) {
1156
- if (item.kind === "summary") {
1157
- summaries.push(await prepareSummary(item));
1158
- continue;
1159
- }
1160
- if (options.prepareEvent && item.rawFrames.length > 0) {
1161
- try {
1162
- events.push(
1163
- await options.prepareEvent({
1164
- event: item.event,
1165
- rawFrames: item.rawFrames
1166
- })
1167
- );
1168
- } catch {
1169
- events.push(item.event);
1170
- }
1171
- } else {
1172
- events.push(item.event);
1173
- }
1174
- }
1175
- const result = await sendBatch({
1176
- ingestUrl: options.ingestUrl,
1177
- projectApiKey: options.projectApiKey,
1178
- events,
1179
- summaries,
1180
- idempotencyKey,
1181
- sdkVersion: options.sdkVersion,
1182
- sdkName: options.sdkName,
1183
- gzipThresholdBytes,
1184
- maxRetries,
1185
- fetch: fetchFn,
1186
- signal: controller.signal
1187
- });
1188
- if (result === "failed") {
1189
- retryBatch = { items: batch, idempotencyKey };
1190
- break;
1191
- }
1192
- }
1193
- } finally {
1194
- if (timeout) clearTimeout(timeout);
1195
- if (queue.size() === 0 && !retryBatch) stopTimer();
1196
- flushing = void 0;
1197
- }
1198
- })();
1199
- return flushing;
1248
+ if (flushing) {
1249
+ flushesJoined++;
1250
+ return flushing;
1251
+ }
1252
+ flushesStarted++;
1253
+ const activeFlush = performFlush(timeoutMs);
1254
+ flushing = activeFlush;
1255
+ try {
1256
+ await activeFlush;
1257
+ } finally {
1258
+ if (flushing === activeFlush) flushing = void 0;
1259
+ }
1200
1260
  };
1201
1261
  const enqueue = (event, priority = "first", rawFrames = []) => {
1202
1262
  if (!enabled || closed) return;
@@ -1248,7 +1308,21 @@ var createTransport = (options) => {
1248
1308
  const queueStats = queue.getStats();
1249
1309
  return {
1250
1310
  ...queueStats,
1251
- queued: queueStats.queued + (retryBatch?.items.length ?? 0)
1311
+ queued: queueStats.queued + (retryBatch?.items.length ?? 0),
1312
+ flushesStarted,
1313
+ flushesJoined,
1314
+ sendAttempts,
1315
+ sendRetries,
1316
+ batchReplays,
1317
+ batchesSucceeded,
1318
+ batchesDropped,
1319
+ batchesFailed,
1320
+ flushTimeouts,
1321
+ networkErrors,
1322
+ rateLimitedResponses,
1323
+ serverErrorResponses,
1324
+ lastFailureKind,
1325
+ lastFailureStatusCode
1252
1326
  };
1253
1327
  }
1254
1328
  };
@@ -1269,7 +1343,21 @@ var noopClient = () => ({
1269
1343
  enqueued: 0,
1270
1344
  droppedIncoming: 0,
1271
1345
  droppedQueued: 0,
1272
- droppedTotal: 0
1346
+ droppedTotal: 0,
1347
+ flushesStarted: 0,
1348
+ flushesJoined: 0,
1349
+ sendAttempts: 0,
1350
+ sendRetries: 0,
1351
+ batchReplays: 0,
1352
+ batchesSucceeded: 0,
1353
+ batchesDropped: 0,
1354
+ batchesFailed: 0,
1355
+ flushTimeouts: 0,
1356
+ networkErrors: 0,
1357
+ rateLimitedResponses: 0,
1358
+ serverErrorResponses: 0,
1359
+ lastFailureKind: null,
1360
+ lastFailureStatusCode: null
1273
1361
  }
1274
1362
  })
1275
1363
  });
@@ -1442,8 +1530,1063 @@ var createClient = (options, hooks = {}) => {
1442
1530
  }
1443
1531
  };
1444
1532
 
1533
+ // src/derivation/rasputin-wire-tag.ts
1534
+ var RASPUTIN_WIRE_TAG = "\0rasputin";
1535
+ var rasputinUnknown = () => [RASPUTIN_WIRE_TAG, "unknown"];
1536
+ var rasputinUnavailable = (reason) => [
1537
+ RASPUTIN_WIRE_TAG,
1538
+ "unavailable",
1539
+ reason
1540
+ ];
1541
+ var rasputinOmitted = () => [RASPUTIN_WIRE_TAG, "omitted"];
1542
+ var rasputinRedacted = () => [RASPUTIN_WIRE_TAG, "redacted"];
1543
+ var rasputinTruncated = (payload) => [
1544
+ RASPUTIN_WIRE_TAG,
1545
+ "truncated",
1546
+ payload
1547
+ ];
1548
+ var isRasputinTaggedValue = (value) => {
1549
+ if (!Array.isArray(value) || value.length < 2 || value[0] !== RASPUTIN_WIRE_TAG) return false;
1550
+ const kind = value[1];
1551
+ return kind === "unknown" || kind === "unavailable" || kind === "omitted" || kind === "redacted" || kind === "truncated";
1552
+ };
1553
+ var rasputinTagKind = (value) => isRasputinTaggedValue(value) ? value[1] : void 0;
1554
+
1555
+ // src/derivation/captured-value-markers.ts
1556
+ var REDACTED = "[RASPUTIN_REDACTED]";
1557
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1558
+ var capturedValueCompleteness = (value) => {
1559
+ if (value === REDACTED) return "partial";
1560
+ const tagged = rasputinTagKind(value);
1561
+ if (tagged === "unknown" || tagged === "truncated" || tagged === "unavailable" || tagged === "omitted") {
1562
+ return "partial";
1563
+ }
1564
+ if (tagged === "redacted") return "partial";
1565
+ if (isRasputinTaggedValue(value)) return "partial";
1566
+ if (Array.isArray(value)) {
1567
+ for (const item of value) {
1568
+ if (capturedValueCompleteness(item) === "partial") return "partial";
1569
+ }
1570
+ return "exact";
1571
+ }
1572
+ if (!isRecord(value)) return "exact";
1573
+ if (value.__rasputin_truncated === true) return "partial";
1574
+ if (value.__rasputin_type === "omitted" || value.__rasputin_type === "accessor") return "partial";
1575
+ if (value.__rasputin_type === "unserializable") return "partial";
1576
+ for (const key of Object.keys(value)) {
1577
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
1578
+ if (!descriptor || descriptor.get || descriptor.set) return "partial";
1579
+ if (capturedValueCompleteness(descriptor.value) === "partial") return "partial";
1580
+ }
1581
+ return "exact";
1582
+ };
1583
+ var isRedactedCapturedValue = (value) => {
1584
+ if (value === REDACTED) return true;
1585
+ if (rasputinTagKind(value) === "redacted") return true;
1586
+ if (isRecord(value) && value.__rasputin_type === "omitted") return true;
1587
+ return false;
1588
+ };
1589
+ var isSerializerMarker = (value) => {
1590
+ if (isRasputinTaggedValue(value)) return true;
1591
+ if (!isRecord(value)) return false;
1592
+ return value.__rasputin_truncated === true || typeof value.__rasputin_type === "string";
1593
+ };
1594
+
1595
+ // src/derivation/canonical-json.ts
1596
+ var sortedKeys = (value) => Object.keys(value).sort();
1597
+ var canonicalJson = (value) => {
1598
+ if (value === null) return "null";
1599
+ switch (typeof value) {
1600
+ case "boolean":
1601
+ return value ? "true" : "false";
1602
+ case "number":
1603
+ if (!Number.isFinite(value)) return "null";
1604
+ if (Object.is(value, -0)) return "0";
1605
+ return String(value);
1606
+ case "string":
1607
+ return JSON.stringify(value);
1608
+ case "undefined":
1609
+ return "null";
1610
+ default:
1611
+ break;
1612
+ }
1613
+ if (Array.isArray(value)) {
1614
+ return `[${value.map((item) => canonicalJson(item)).join(",")}]`;
1615
+ }
1616
+ if (typeof value === "object") {
1617
+ const record = value;
1618
+ const fields = sortedKeys(record).filter((key) => record[key] !== void 0).map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`);
1619
+ return `{${fields.join(",")}}`;
1620
+ }
1621
+ return "null";
1622
+ };
1623
+
1624
+ // src/derivation/sha256.ts
1625
+ var K = [
1626
+ 1116352408,
1627
+ 1899447441,
1628
+ 3049323471,
1629
+ 3921009573,
1630
+ 961987163,
1631
+ 1508970993,
1632
+ 2453635748,
1633
+ 2870763221,
1634
+ 3624381080,
1635
+ 310598401,
1636
+ 607225278,
1637
+ 1426881987,
1638
+ 1925078388,
1639
+ 2162078206,
1640
+ 2614888103,
1641
+ 3248222580,
1642
+ 3835390401,
1643
+ 4022224774,
1644
+ 264347078,
1645
+ 604807628,
1646
+ 770255983,
1647
+ 1249150122,
1648
+ 1555081692,
1649
+ 1996064986,
1650
+ 2554220882,
1651
+ 2821834349,
1652
+ 2952996808,
1653
+ 3210313671,
1654
+ 3336571891,
1655
+ 3584528711,
1656
+ 113926993,
1657
+ 338241895,
1658
+ 666307205,
1659
+ 773529912,
1660
+ 1294757372,
1661
+ 1396182291,
1662
+ 1695183700,
1663
+ 1986661051,
1664
+ 2177026350,
1665
+ 2456956037,
1666
+ 2730485921,
1667
+ 2820302411,
1668
+ 3259730800,
1669
+ 3345764771,
1670
+ 3516065817,
1671
+ 3600352804,
1672
+ 4094571909,
1673
+ 275423344,
1674
+ 430227734,
1675
+ 506948616,
1676
+ 659060556,
1677
+ 883997877,
1678
+ 958139571,
1679
+ 1322822218,
1680
+ 1537002063,
1681
+ 1747873779,
1682
+ 1955562222,
1683
+ 2024104815,
1684
+ 2227730452,
1685
+ 2361852424,
1686
+ 2428436474,
1687
+ 2756734187,
1688
+ 3204031479,
1689
+ 3329325298
1690
+ ];
1691
+ var rotr = (value, bits) => value >>> bits | value << 32 - bits;
1692
+ var sha256Hex = (input) => {
1693
+ const encoded = new TextEncoder().encode(input);
1694
+ const bitLen = encoded.length * 8;
1695
+ const paddedLen = encoded.length + 9 + 63 >> 6 << 6 >>> 0;
1696
+ const bytes = new Uint8Array(paddedLen);
1697
+ bytes.set(encoded);
1698
+ bytes[encoded.length] = 128;
1699
+ const view = new DataView(bytes.buffer);
1700
+ view.setUint32(paddedLen - 4, bitLen, false);
1701
+ let h0 = 1779033703;
1702
+ let h1 = 3144134277;
1703
+ let h2 = 1013904242;
1704
+ let h3 = 2773480762;
1705
+ let h4 = 1359893119;
1706
+ let h5 = 2600822924;
1707
+ let h6 = 528734635;
1708
+ let h7 = 1541459225;
1709
+ const w = new Uint32Array(64);
1710
+ for (let offset = 0; offset < paddedLen; offset += 64) {
1711
+ for (let i = 0; i < 16; i++) w[i] = view.getUint32(offset + i * 4, false);
1712
+ for (let i = 16; i < 64; i++) {
1713
+ const s0 = rotr(w[i - 15], 7) ^ rotr(w[i - 15], 18) ^ w[i - 15] >>> 3;
1714
+ const s1 = rotr(w[i - 2], 17) ^ rotr(w[i - 2], 19) ^ w[i - 2] >>> 10;
1715
+ w[i] = w[i - 16] + s0 + w[i - 7] + s1 >>> 0;
1716
+ }
1717
+ let a = h0;
1718
+ let b = h1;
1719
+ let c = h2;
1720
+ let d = h3;
1721
+ let e = h4;
1722
+ let f = h5;
1723
+ let g = h6;
1724
+ let h = h7;
1725
+ for (let i = 0; i < 64; i++) {
1726
+ const S1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25);
1727
+ const ch = e & f ^ ~e & g;
1728
+ const temp1 = h + S1 + ch + K[i] + w[i] >>> 0;
1729
+ const S0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22);
1730
+ const maj = a & b ^ a & c ^ b & c;
1731
+ const temp2 = S0 + maj >>> 0;
1732
+ h = g;
1733
+ g = f;
1734
+ f = e;
1735
+ e = d + temp1 >>> 0;
1736
+ d = c;
1737
+ c = b;
1738
+ b = a;
1739
+ a = temp1 + temp2 >>> 0;
1740
+ }
1741
+ h0 = h0 + a >>> 0;
1742
+ h1 = h1 + b >>> 0;
1743
+ h2 = h2 + c >>> 0;
1744
+ h3 = h3 + d >>> 0;
1745
+ h4 = h4 + e >>> 0;
1746
+ h5 = h5 + f >>> 0;
1747
+ h6 = h6 + g >>> 0;
1748
+ h7 = h7 + h >>> 0;
1749
+ }
1750
+ return [h0, h1, h2, h3, h4, h5, h6, h7].map((word) => word.toString(16).padStart(8, "0")).join("");
1751
+ };
1752
+
1753
+ // src/derivation/hash-instrumentation-manifest.ts
1754
+ var hashableSource = (source) => {
1755
+ const { repositoryPath: _repositoryPath, ...rest } = source;
1756
+ return rest;
1757
+ };
1758
+ var hashableLocated = (items) => items.map((item) => ({ ...item, source: hashableSource(item.source) }));
1759
+ var hashInstrumentationManifest = (manifest) => {
1760
+ return sha256Hex(
1761
+ canonicalJson({
1762
+ schema_version: manifest.schema_version,
1763
+ functions: hashableLocated(manifest.functions),
1764
+ callSites: hashableLocated(manifest.callSites),
1765
+ destructures: hashableLocated(manifest.destructures),
1766
+ derivationPlans: manifest.derivationPlans ?? []
1767
+ })
1768
+ );
1769
+ };
1770
+
1771
+ // src/derivation/wire-values-equal.ts
1772
+ var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1773
+ var arraysEqual = (left, right) => {
1774
+ if (left.length !== right.length) return false;
1775
+ for (let index = 0; index < left.length; index++) {
1776
+ if (Object.hasOwn(left, index) !== Object.hasOwn(right, index)) return false;
1777
+ if (!wireValuesEqual(left[index], right[index])) return false;
1778
+ }
1779
+ return true;
1780
+ };
1781
+ var wireValuesEqual = (left, right) => {
1782
+ if (Object.is(left, right)) return true;
1783
+ if (typeof left === "bigint" && typeof right === "bigint") return left === right;
1784
+ if (isRasputinTaggedValue(left) || isRasputinTaggedValue(right)) {
1785
+ if (!Array.isArray(left) || !Array.isArray(right)) return false;
1786
+ return arraysEqual(left, right);
1787
+ }
1788
+ if (Array.isArray(left) && Array.isArray(right)) return arraysEqual(left, right);
1789
+ if (!isRecord2(left) || !isRecord2(right)) return false;
1790
+ const leftKeys = Object.keys(left).sort();
1791
+ const rightKeys = Object.keys(right).sort();
1792
+ if (leftKeys.length !== rightKeys.length) return false;
1793
+ return leftKeys.every((key, index) => {
1794
+ if (key !== rightKeys[index]) return false;
1795
+ const leftDesc = Object.getOwnPropertyDescriptor(left, key);
1796
+ const rightDesc = Object.getOwnPropertyDescriptor(right, key);
1797
+ if (!leftDesc || !rightDesc) return false;
1798
+ if (leftDesc.get || leftDesc.set || rightDesc.get || rightDesc.set) return false;
1799
+ return wireValuesEqual(leftDesc.value, rightDesc.value);
1800
+ });
1801
+ };
1802
+
1803
+ // src/derivation/evaluate-derivation-plan.ts
1804
+ var MAX_INSTRUCTIONS = 1e4;
1805
+ var MAX_DEPTH = 64;
1806
+ var MAX_OUTPUT_BYTES = 256 * 1024;
1807
+ var MAX_WALL_MS = 50;
1808
+ var isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1809
+ var primitiveFromConst = (value) => {
1810
+ switch (value.type) {
1811
+ case "null":
1812
+ return null;
1813
+ case "undefined":
1814
+ return void 0;
1815
+ case "boolean":
1816
+ return value.value;
1817
+ case "number":
1818
+ return value.negativeZero ? -0 : value.value;
1819
+ case "string":
1820
+ return value.value;
1821
+ case "bigint":
1822
+ try {
1823
+ return BigInt(value.value);
1824
+ } catch {
1825
+ return rasputinUnavailable("invalid_bigint_const");
1826
+ }
1827
+ }
1828
+ };
1829
+ var estimateBytes = (value, depth = 0) => {
1830
+ if (value === null || value === void 0) return 4;
1831
+ switch (typeof value) {
1832
+ case "boolean":
1833
+ return 4;
1834
+ case "number":
1835
+ return 8;
1836
+ case "string":
1837
+ return value.length;
1838
+ case "bigint":
1839
+ return value.toString().length;
1840
+ case "object": {
1841
+ if (depth > 8) return 8;
1842
+ if (Array.isArray(value)) {
1843
+ let total2 = 2;
1844
+ for (const item of value) total2 += estimateBytes(item, depth + 1);
1845
+ return total2;
1846
+ }
1847
+ let total = 2;
1848
+ for (const key of Object.keys(value)) {
1849
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
1850
+ if (!descriptor || descriptor.get || descriptor.set) {
1851
+ total += key.length + 8;
1852
+ continue;
1853
+ }
1854
+ total += key.length + estimateBytes(descriptor.value, depth + 1);
1855
+ }
1856
+ return total;
1857
+ }
1858
+ default:
1859
+ return 8;
1860
+ }
1861
+ };
1862
+ var capturedFromWire = (value) => {
1863
+ if (rasputinTagKind(value) === "omitted") {
1864
+ return { origin: "unavailable", reason: "omitted_value" };
1865
+ }
1866
+ if (isRedactedCapturedValue(value)) {
1867
+ return { origin: "captured", completeness: "partial", value: rasputinRedacted() };
1868
+ }
1869
+ return { origin: "captured", completeness: capturedValueCompleteness(value), value };
1870
+ };
1871
+ var checkpointRank = (value) => {
1872
+ if (!value || value.origin === "unavailable") return 5;
1873
+ if (value.origin === "captured" && value.completeness === "exact") return 1;
1874
+ if (value.origin === "derived" && value.completeness === "exact") return 2;
1875
+ if (value.origin === "captured") return 3;
1876
+ return 4;
1877
+ };
1878
+ var resolveCheckpoint = (captured, derived, expressionId) => {
1879
+ const capturedRank = checkpointRank(captured);
1880
+ const derivedRank = checkpointRank(derived);
1881
+ if (capturedRank === 1 && derivedRank === 2 && captured?.origin === "captured" && derived?.origin === "derived") {
1882
+ if (!wireValuesEqual(captured.value, derived.value)) {
1883
+ return {
1884
+ origin: "captured",
1885
+ completeness: "exact",
1886
+ value: captured.value,
1887
+ derivationValidation: {
1888
+ status: "mismatch",
1889
+ derivedValue: derived.value,
1890
+ expressionId,
1891
+ dependencies: derived.dependencies
1892
+ }
1893
+ };
1894
+ }
1895
+ return {
1896
+ origin: "captured",
1897
+ completeness: "exact",
1898
+ value: captured.value,
1899
+ derivationValidation: { status: "verified" }
1900
+ };
1901
+ }
1902
+ if (capturedRank <= derivedRank) {
1903
+ return captured ?? derived ?? { origin: "unavailable", reason: "no_checkpoint" };
1904
+ }
1905
+ return derived ?? { origin: "unavailable", reason: "no_checkpoint" };
1906
+ };
1907
+ var exactOperandsOrUnavailable = (parts) => {
1908
+ const completeness = mergeCompleteness(parts);
1909
+ if (completeness === "unavailable")
1910
+ return { origin: "unavailable", reason: "partial_dependency" };
1911
+ if (completeness === "partial") return { origin: "unavailable", reason: "partial_operand" };
1912
+ return void 0;
1913
+ };
1914
+ var capturedResult = (root) => {
1915
+ if (isRedactedCapturedValue(root.value)) {
1916
+ return { origin: "captured", completeness: "partial", value: rasputinRedacted() };
1917
+ }
1918
+ const completeness = root.completeness === "partial" ? "partial" : capturedValueCompleteness(root.value);
1919
+ return { origin: "captured", completeness, value: root.value };
1920
+ };
1921
+ var mergeCompleteness = (parts) => {
1922
+ let partial = false;
1923
+ for (const part of parts) {
1924
+ if (part.origin === "unavailable") return "unavailable";
1925
+ if (part.completeness === "partial") partial = true;
1926
+ }
1927
+ return partial ? "partial" : "exact";
1928
+ };
1929
+ var unwrapExactPrimitive = (result) => {
1930
+ if (result.origin === "unavailable") return rasputinUnavailable(result.reason);
1931
+ return result.value;
1932
+ };
1933
+ var isNumericPrimitive = (value) => typeof value === "number" && !isRasputinTaggedValue(value);
1934
+ var isPrimitiveOperand = (value) => {
1935
+ if (isRasputinTaggedValue(value)) return false;
1936
+ return value === null || typeof value === "boolean" || typeof value === "number" || typeof value === "string" || typeof value === "bigint" || typeof value === "undefined";
1937
+ };
1938
+ var omittedCallKey = (parentCallId, functionId) => `${parentCallId}\0${functionId}`;
1939
+ var argsIncludeOmitted = (args) => args.some((arg) => rasputinTagKind(arg) === "omitted");
1940
+ var recordReconstructedCallArgs = (queue, parentCallId, functionId, args) => {
1941
+ const key = omittedCallKey(parentCallId, functionId);
1942
+ const pending = queue.get(key);
1943
+ if (pending) pending.push(args);
1944
+ else queue.set(key, [args]);
1945
+ };
1946
+ var takeReconstructedCallArgs = (queue, parentCallId, functionId) => {
1947
+ if (parentCallId == null) return void 0;
1948
+ const pending = queue.get(omittedCallKey(parentCallId, functionId));
1949
+ if (!pending || pending.length === 0) return void 0;
1950
+ return pending.shift();
1951
+ };
1952
+ var resolveEnterArgs = (enter, queue) => {
1953
+ if (!argsIncludeOmitted(enter.args)) return enter.args;
1954
+ return takeReconstructedCallArgs(queue, enter.parentCallId, enter.functionId) ?? enter.args;
1955
+ };
1956
+ var takeChildCapturedReturn = (state, calleeFunctionId) => {
1957
+ if (state.recordingCallId == null) return void 0;
1958
+ const children = (state.childrenByParent.get(state.recordingCallId) ?? []).filter(
1959
+ (child2) => child2.functionId === calleeFunctionId
1960
+ );
1961
+ const key = omittedCallKey(state.recordingCallId, calleeFunctionId);
1962
+ const index = state.childCursor.get(key) ?? 0;
1963
+ state.childCursor.set(key, index + 1);
1964
+ const child = children[index];
1965
+ if (!child) return void 0;
1966
+ if (state.throwCallIds.has(child.callId)) return { threw: true };
1967
+ return state.exitByCallId.get(child.callId);
1968
+ };
1969
+ var readOwnDataProperty = (object, key) => {
1970
+ const descriptor = Object.getOwnPropertyDescriptor(object, key);
1971
+ if (!descriptor) return { ok: false, reason: "missing_property" };
1972
+ if (descriptor.get !== void 0 || descriptor.set !== void 0) {
1973
+ return { ok: false, reason: "accessor_property" };
1974
+ }
1975
+ return { ok: true, value: descriptor.value };
1976
+ };
1977
+ var budgetExceeded = (state) => {
1978
+ if (state.instructions > MAX_INSTRUCTIONS) return "instruction_budget";
1979
+ if (state.depth > MAX_DEPTH) return "depth_budget";
1980
+ if (state.outputBytes > MAX_OUTPUT_BYTES) return "output_size_budget";
1981
+ if (Date.now() - state.startedAt > MAX_WALL_MS) return "wall_time_budget";
1982
+ return void 0;
1983
+ };
1984
+ var evaluateExpression = (expressionId, plan, byId, cells, args, rootsById, factsById, calleeReturns, state, evaluateCallee) => {
1985
+ const over = budgetExceeded(state);
1986
+ if (over) return { origin: "unavailable", reason: over };
1987
+ state.instructions++;
1988
+ state.depth++;
1989
+ try {
1990
+ const existing = cells.get(expressionId);
1991
+ if (existing?.status === "done") return existing.result;
1992
+ if (existing?.status === "pending") {
1993
+ return { origin: "unavailable", reason: "cyclic_expression" };
1994
+ }
1995
+ const expression = byId.get(expressionId);
1996
+ if (!expression) return { origin: "unavailable", reason: "missing_expression" };
1997
+ cells.set(expressionId, { status: "pending" });
1998
+ const evalChild = (id) => evaluateExpression(
1999
+ id,
2000
+ plan,
2001
+ byId,
2002
+ cells,
2003
+ args,
2004
+ rootsById,
2005
+ factsById,
2006
+ calleeReturns,
2007
+ state,
2008
+ evaluateCallee
2009
+ );
2010
+ let result;
2011
+ switch (expression.kind) {
2012
+ case "const": {
2013
+ const value = primitiveFromConst(expression.value);
2014
+ result = { origin: "derived", completeness: "exact", value, dependencies: [] };
2015
+ break;
2016
+ }
2017
+ case "param": {
2018
+ if (expression.index < 0 || expression.index >= args.length) {
2019
+ result = { origin: "unavailable", reason: "missing_argument" };
2020
+ break;
2021
+ }
2022
+ const value = args[expression.index];
2023
+ if (rasputinTagKind(value) === "omitted") {
2024
+ result = { origin: "unavailable", reason: "omitted_argument" };
2025
+ break;
2026
+ }
2027
+ result = capturedFromWire(value);
2028
+ break;
2029
+ }
2030
+ case "root": {
2031
+ const root = rootsById.get(expression.rootId);
2032
+ if (!root) {
2033
+ result = { origin: "unavailable", reason: "missing_root" };
2034
+ break;
2035
+ }
2036
+ result = capturedResult(root);
2037
+ break;
2038
+ }
2039
+ case "alias":
2040
+ result = evalChild(expression.from);
2041
+ break;
2042
+ case "binary": {
2043
+ const left = evalChild(expression.left);
2044
+ const right = evalChild(expression.right);
2045
+ const blocked = exactOperandsOrUnavailable([left, right]);
2046
+ if (blocked) {
2047
+ result = blocked;
2048
+ break;
2049
+ }
2050
+ const leftValue = unwrapExactPrimitive(left);
2051
+ const rightValue = unwrapExactPrimitive(right);
2052
+ if (rasputinTagKind(leftValue) || rasputinTagKind(rightValue)) {
2053
+ result = { origin: "unavailable", reason: "tagged_operand" };
2054
+ break;
2055
+ }
2056
+ if (isRedactedCapturedValue(leftValue) || isRedactedCapturedValue(rightValue)) {
2057
+ result = { origin: "unavailable", reason: "redacted_operand" };
2058
+ break;
2059
+ }
2060
+ if (expression.guard === "numeric") {
2061
+ if (!isNumericPrimitive(leftValue) || !isNumericPrimitive(rightValue)) {
2062
+ result = { origin: "unavailable", reason: "numeric_guard_failed" };
2063
+ break;
2064
+ }
2065
+ } else if (expression.guard === "primitive") {
2066
+ if (!isPrimitiveOperand(leftValue) || !isPrimitiveOperand(rightValue)) {
2067
+ result = { origin: "unavailable", reason: "primitive_guard_failed" };
2068
+ break;
2069
+ }
2070
+ }
2071
+ const value = applyBinary(expression.op, leftValue, rightValue);
2072
+ if (value === void 0) {
2073
+ result = { origin: "unavailable", reason: "unsupported_binary" };
2074
+ break;
2075
+ }
2076
+ result = {
2077
+ origin: "derived",
2078
+ completeness: "exact",
2079
+ value,
2080
+ dependencies: [expression.left, expression.right]
2081
+ };
2082
+ break;
2083
+ }
2084
+ case "unary": {
2085
+ const operand = evalChild(expression.operand);
2086
+ const blocked = exactOperandsOrUnavailable([operand]);
2087
+ if (blocked || operand.origin === "unavailable") {
2088
+ result = blocked ?? operand;
2089
+ break;
2090
+ }
2091
+ const raw = operand.value;
2092
+ if (isRedactedCapturedValue(raw) || rasputinTagKind(raw)) {
2093
+ result = { origin: "unavailable", reason: "tagged_operand" };
2094
+ break;
2095
+ }
2096
+ if (expression.op === "typeof") {
2097
+ result = {
2098
+ origin: "derived",
2099
+ completeness: "exact",
2100
+ value: typeof raw,
2101
+ dependencies: [expression.operand]
2102
+ };
2103
+ break;
2104
+ }
2105
+ if (expression.op === "not") {
2106
+ result = {
2107
+ origin: "derived",
2108
+ completeness: "exact",
2109
+ value: !raw,
2110
+ dependencies: [expression.operand]
2111
+ };
2112
+ break;
2113
+ }
2114
+ if (!isNumericPrimitive(raw)) {
2115
+ result = { origin: "unavailable", reason: "numeric_guard_failed" };
2116
+ break;
2117
+ }
2118
+ result = {
2119
+ origin: "derived",
2120
+ completeness: "exact",
2121
+ value: expression.op === "minus" ? -raw : +raw,
2122
+ dependencies: [expression.operand]
2123
+ };
2124
+ break;
2125
+ }
2126
+ case "logical": {
2127
+ const left = evalChild(expression.left);
2128
+ const leftBlocked = exactOperandsOrUnavailable([left]);
2129
+ if (leftBlocked || left.origin === "unavailable") {
2130
+ result = leftBlocked ?? left;
2131
+ break;
2132
+ }
2133
+ const takeRight = expression.op === "and" ? Boolean(left.value) : expression.op === "or" ? !left.value : left.value == null;
2134
+ if (!takeRight) {
2135
+ result = left.origin === "derived" ? left : {
2136
+ origin: "derived",
2137
+ completeness: "exact",
2138
+ value: left.value,
2139
+ dependencies: [expression.left]
2140
+ };
2141
+ break;
2142
+ }
2143
+ const right = evalChild(expression.right);
2144
+ const blocked = exactOperandsOrUnavailable([left, right]);
2145
+ if (blocked || right.origin === "unavailable") {
2146
+ result = blocked ?? right;
2147
+ break;
2148
+ }
2149
+ result = {
2150
+ origin: "derived",
2151
+ completeness: "exact",
2152
+ value: right.value,
2153
+ dependencies: [expression.left, expression.right]
2154
+ };
2155
+ break;
2156
+ }
2157
+ case "cond": {
2158
+ const test = evalChild(expression.test);
2159
+ const testBlocked = exactOperandsOrUnavailable([test]);
2160
+ if (testBlocked || test.origin === "unavailable") {
2161
+ result = testBlocked ?? test;
2162
+ break;
2163
+ }
2164
+ const fact = [...factsById.values()].find(
2165
+ (entry) => plan.controlFacts.some((definition) => definition.id === entry.factId)
2166
+ );
2167
+ const takeConsequent = fact ? fact.value : Boolean(test.value);
2168
+ const branch = evalChild(takeConsequent ? expression.consequent : expression.alternate);
2169
+ const blocked = exactOperandsOrUnavailable([test, branch]);
2170
+ if (blocked || branch.origin === "unavailable") {
2171
+ result = blocked ?? branch;
2172
+ break;
2173
+ }
2174
+ result = {
2175
+ origin: "derived",
2176
+ completeness: "exact",
2177
+ value: branch.value,
2178
+ dependencies: [
2179
+ expression.test,
2180
+ takeConsequent ? expression.consequent : expression.alternate
2181
+ ]
2182
+ };
2183
+ break;
2184
+ }
2185
+ case "template": {
2186
+ const parts = [];
2187
+ let text = "";
2188
+ let failed;
2189
+ for (const part of expression.parts) {
2190
+ if (part.kind === "lit") {
2191
+ text += part.value;
2192
+ continue;
2193
+ }
2194
+ const nested = evalChild(part.expressionId);
2195
+ parts.push(nested);
2196
+ if (nested.origin === "unavailable") {
2197
+ failed = nested;
2198
+ break;
2199
+ }
2200
+ if (!isPrimitiveOperand(nested.value) || isRasputinTaggedValue(nested.value)) {
2201
+ failed = { origin: "unavailable", reason: "template_non_primitive" };
2202
+ break;
2203
+ }
2204
+ text += String(nested.value);
2205
+ }
2206
+ if (failed) {
2207
+ result = failed;
2208
+ break;
2209
+ }
2210
+ const completeness = parts.length === 0 ? "exact" : mergeCompleteness(parts);
2211
+ if (completeness === "unavailable") {
2212
+ result = { origin: "unavailable", reason: "partial_dependency" };
2213
+ break;
2214
+ }
2215
+ result = {
2216
+ origin: "derived",
2217
+ completeness,
2218
+ value: text,
2219
+ dependencies: expression.parts.flatMap(
2220
+ (part) => part.kind === "expr" ? [part.expressionId] : []
2221
+ )
2222
+ };
2223
+ break;
2224
+ }
2225
+ case "object": {
2226
+ const record = {};
2227
+ const parts = [];
2228
+ let failed;
2229
+ for (const property of expression.properties) {
2230
+ const nested = evalChild(property.value);
2231
+ parts.push(nested);
2232
+ if (nested.origin === "unavailable") {
2233
+ failed = nested;
2234
+ break;
2235
+ }
2236
+ record[property.key] = nested.value;
2237
+ }
2238
+ if (failed) {
2239
+ result = failed;
2240
+ break;
2241
+ }
2242
+ const completeness = mergeCompleteness(parts);
2243
+ if (completeness === "unavailable") {
2244
+ result = { origin: "unavailable", reason: "partial_dependency" };
2245
+ break;
2246
+ }
2247
+ result = {
2248
+ origin: "derived",
2249
+ completeness,
2250
+ value: record,
2251
+ dependencies: expression.properties.map((property) => property.value)
2252
+ };
2253
+ break;
2254
+ }
2255
+ case "array": {
2256
+ const items = [];
2257
+ const parts = [];
2258
+ let failed;
2259
+ let unknownCount = 0;
2260
+ for (const element of expression.elements) {
2261
+ if (typeof element !== "number") {
2262
+ items.push(rasputinUnknown());
2263
+ unknownCount++;
2264
+ continue;
2265
+ }
2266
+ const nested = evalChild(element);
2267
+ parts.push(nested);
2268
+ if (nested.origin === "unavailable") {
2269
+ failed = nested;
2270
+ break;
2271
+ }
2272
+ items.push(nested.value);
2273
+ }
2274
+ if (failed) {
2275
+ result = failed;
2276
+ break;
2277
+ }
2278
+ const completeness = unknownCount > 0 ? "partial" : parts.length === 0 ? "exact" : mergeCompleteness(parts);
2279
+ if (completeness === "unavailable") {
2280
+ result = { origin: "unavailable", reason: "partial_dependency" };
2281
+ break;
2282
+ }
2283
+ result = {
2284
+ origin: "derived",
2285
+ completeness,
2286
+ value: items,
2287
+ dependencies: expression.elements.flatMap(
2288
+ (element) => typeof element === "number" ? [element] : []
2289
+ )
2290
+ };
2291
+ break;
2292
+ }
2293
+ case "prop": {
2294
+ const object = evalChild(expression.object);
2295
+ if (object.origin === "unavailable") {
2296
+ result = object;
2297
+ break;
2298
+ }
2299
+ if (isRedactedCapturedValue(object.value)) {
2300
+ result = { origin: "unavailable", reason: "redacted_operand" };
2301
+ break;
2302
+ }
2303
+ if (!isRecord3(object.value) || rasputinTagKind(object.value)) {
2304
+ result = { origin: "unavailable", reason: "prop_on_non_object" };
2305
+ break;
2306
+ }
2307
+ const owned = readOwnDataProperty(object.value, expression.key);
2308
+ if (!owned.ok) {
2309
+ result = { origin: "unavailable", reason: owned.reason };
2310
+ break;
2311
+ }
2312
+ const completeness = object.completeness === "partial" || capturedValueCompleteness(owned.value) === "partial" ? "partial" : "exact";
2313
+ result = {
2314
+ origin: "derived",
2315
+ completeness,
2316
+ value: owned.value,
2317
+ dependencies: [expression.object]
2318
+ };
2319
+ break;
2320
+ }
2321
+ case "index": {
2322
+ const array = evalChild(expression.array);
2323
+ if (array.origin === "unavailable") {
2324
+ result = array;
2325
+ break;
2326
+ }
2327
+ if (!Array.isArray(array.value)) {
2328
+ result = { origin: "unavailable", reason: "index_on_non_array" };
2329
+ break;
2330
+ }
2331
+ if (expression.index < 0 || expression.index >= array.value.length) {
2332
+ result = { origin: "unavailable", reason: "index_out_of_range" };
2333
+ break;
2334
+ }
2335
+ const value = array.value[expression.index];
2336
+ if (rasputinTagKind(value) === "unknown") {
2337
+ result = { origin: "unavailable", reason: "array_hole" };
2338
+ break;
2339
+ }
2340
+ const completeness = array.completeness === "partial" || capturedValueCompleteness(value) === "partial" ? "partial" : "exact";
2341
+ result = {
2342
+ origin: "derived",
2343
+ completeness,
2344
+ value,
2345
+ dependencies: [expression.array]
2346
+ };
2347
+ break;
2348
+ }
2349
+ case "pure_call": {
2350
+ const childReturn = takeChildCapturedReturn(state, expression.calleeFunctionId);
2351
+ if (childReturn && "threw" in childReturn) {
2352
+ result = { origin: "unavailable", reason: "callee_threw" };
2353
+ break;
2354
+ }
2355
+ const capturedReturn = childReturn && "present" in childReturn ? capturedFromWire(childReturn.value) : void 0;
2356
+ const callee = calleeReturns.get(expression.calleeFunctionId);
2357
+ const callArgs = [];
2358
+ let argsExact = true;
2359
+ for (const argId of expression.args) {
2360
+ const nested = evalChild(argId);
2361
+ if (nested.origin === "unavailable" || nested.completeness === "partial") {
2362
+ argsExact = false;
2363
+ continue;
2364
+ }
2365
+ callArgs.push(nested.value);
2366
+ }
2367
+ if (argsExact && state.recordingCallId != null) {
2368
+ recordReconstructedCallArgs(
2369
+ state.omittedCallArgs,
2370
+ state.recordingCallId,
2371
+ expression.calleeFunctionId,
2372
+ callArgs
2373
+ );
2374
+ }
2375
+ const canDeriveCallee = Boolean(
2376
+ argsExact && callee && !callee.fallbackReason && callee.returnExpressionId != null
2377
+ );
2378
+ const derivedReturn = canDeriveCallee && callee ? evaluateCallee(callee, callArgs) : void 0;
2379
+ result = resolveCheckpoint(capturedReturn, derivedReturn, expression.id);
2380
+ break;
2381
+ }
2382
+ }
2383
+ if (result.origin !== "unavailable") {
2384
+ state.outputBytes += estimateBytes(result.value);
2385
+ const sizeOver = budgetExceeded(state);
2386
+ if (sizeOver) result = { origin: "unavailable", reason: sizeOver };
2387
+ }
2388
+ if (result.origin === "derived" && result.completeness === "exact") {
2389
+ for (const dep of result.dependencies) {
2390
+ const child = cells.get(dep);
2391
+ if (child?.status === "done" && child.result.origin !== "unavailable") {
2392
+ if (child.result.completeness === "partial") {
2393
+ result = { ...result, completeness: "partial" };
2394
+ break;
2395
+ }
2396
+ }
2397
+ }
2398
+ }
2399
+ cells.set(expressionId, { status: "done", result });
2400
+ return result;
2401
+ } finally {
2402
+ state.depth--;
2403
+ }
2404
+ };
2405
+ var isJsPrimitive = (value) => {
2406
+ const type = typeof value;
2407
+ return value === null || type !== "object" && type !== "function";
2408
+ };
2409
+ var abstractEquals = (left, right) => {
2410
+ if (!isJsPrimitive(left) || !isJsPrimitive(right)) return void 0;
2411
+ return left == right;
2412
+ };
2413
+ var applyBinary = (op, left, right) => {
2414
+ if (op === "add" && typeof left === "number" && typeof right === "number") return left + right;
2415
+ if (op === "add" && typeof left === "string" && typeof right === "string") return left + right;
2416
+ if (typeof left !== "number" || typeof right !== "number") {
2417
+ if (op === "eq") return abstractEquals(left, right);
2418
+ if (op === "neq") {
2419
+ const equal = abstractEquals(left, right);
2420
+ return equal === void 0 ? void 0 : !equal;
2421
+ }
2422
+ if (op === "seq") return left === right;
2423
+ if (op === "sneq") return left !== right;
2424
+ return void 0;
2425
+ }
2426
+ switch (op) {
2427
+ case "add":
2428
+ return left + right;
2429
+ case "sub":
2430
+ return left - right;
2431
+ case "mul":
2432
+ return left * right;
2433
+ case "div":
2434
+ return left / right;
2435
+ case "mod":
2436
+ return left % right;
2437
+ case "eq":
2438
+ return left === right;
2439
+ case "neq":
2440
+ return left !== right;
2441
+ case "seq":
2442
+ return left === right;
2443
+ case "sneq":
2444
+ return left !== right;
2445
+ case "lt":
2446
+ return left < right;
2447
+ case "lte":
2448
+ return left <= right;
2449
+ case "gt":
2450
+ return left > right;
2451
+ case "gte":
2452
+ return left >= right;
2453
+ }
2454
+ };
2455
+ var evaluatePlan = (plan, args, roots, facts, plansByFunctionId, state, recordingCallId, capturedExit, threw = false) => {
2456
+ const previousRecordingCallId = state.recordingCallId;
2457
+ state.recordingCallId = recordingCallId;
2458
+ try {
2459
+ const byId = new Map(plan.expressions.map((expression) => [expression.id, expression]));
2460
+ const cells = /* @__PURE__ */ new Map();
2461
+ const rootsById = new Map(roots.map((root) => [root.rootId, root]));
2462
+ const factsById = new Map(facts.map((fact) => [fact.factId, fact]));
2463
+ const evaluateCallee = (callee, callArgs) => {
2464
+ if (callee.returnExpressionId == null) {
2465
+ return { origin: "unavailable", reason: "callee_without_return" };
2466
+ }
2467
+ const nested = evaluatePlan(callee, callArgs, [], [], plansByFunctionId, state, null);
2468
+ return nested.returnValue ?? { origin: "unavailable", reason: "callee_without_return" };
2469
+ };
2470
+ const values = {};
2471
+ for (const expression of plan.expressions) {
2472
+ values[expression.id] = evaluateExpression(
2473
+ expression.id,
2474
+ plan,
2475
+ byId,
2476
+ cells,
2477
+ args,
2478
+ rootsById,
2479
+ factsById,
2480
+ plansByFunctionId,
2481
+ state,
2482
+ evaluateCallee
2483
+ );
2484
+ }
2485
+ const variables = plan.variables.map((variable) => ({
2486
+ variableId: variable.id,
2487
+ name: variable.name,
2488
+ availableAtLine: variable.availableAtLine,
2489
+ availableAtColumn: variable.availableAtColumn,
2490
+ result: values[variable.expressionId] ?? {
2491
+ origin: "unavailable",
2492
+ reason: "missing_expression"
2493
+ }
2494
+ }));
2495
+ const derivedReturn = plan.returnExpressionId == null ? void 0 : values[plan.returnExpressionId] ?? {
2496
+ origin: "unavailable",
2497
+ reason: "missing_return"
2498
+ };
2499
+ return {
2500
+ functionId: plan.functionId,
2501
+ callId: roots[0]?.callId ?? facts[0]?.callId ?? 0,
2502
+ values,
2503
+ variables,
2504
+ returnValue: threw ? void 0 : resolveCheckpoint(
2505
+ capturedExit ? capturedFromWire(capturedExit.value) : void 0,
2506
+ derivedReturn,
2507
+ plan.returnExpressionId
2508
+ )
2509
+ };
2510
+ } finally {
2511
+ state.recordingCallId = previousRecordingCallId;
2512
+ }
2513
+ };
2514
+ var evaluateRuntimeDerivation = (input) => {
2515
+ if (!input.manifest) {
2516
+ return { unavailableReason: "missing_manifest", functions: [] };
2517
+ }
2518
+ if (input.manifest.schema_version !== 3) {
2519
+ return { unavailableReason: "manifest_version_mismatch", functions: [] };
2520
+ }
2521
+ const expectedHash = input.state.derivation?.manifestHash;
2522
+ if (!expectedHash) {
2523
+ return { unavailableReason: "missing_manifest_hash", functions: [] };
2524
+ }
2525
+ if (hashInstrumentationManifest(input.manifest) !== expectedHash) {
2526
+ return { unavailableReason: "manifest_hash_mismatch", functions: [] };
2527
+ }
2528
+ const plansByFunctionId = new Map(
2529
+ (input.manifest.derivationPlans ?? []).map((plan) => [plan.functionId, plan])
2530
+ );
2531
+ const roots = input.state.derivation?.roots ?? [];
2532
+ const facts = input.state.derivation?.controlFacts ?? [];
2533
+ const exitByCallId = /* @__PURE__ */ new Map();
2534
+ const throwCallIds = /* @__PURE__ */ new Set();
2535
+ const childrenByParent = /* @__PURE__ */ new Map();
2536
+ for (const event of input.state.events) {
2537
+ if (event.type === "function_enter" && event.parentCallId != null) {
2538
+ const child = { callId: event.callId, functionId: event.functionId };
2539
+ const siblings = childrenByParent.get(event.parentCallId);
2540
+ if (siblings) siblings.push(child);
2541
+ else childrenByParent.set(event.parentCallId, [child]);
2542
+ }
2543
+ if (event.type === "function_exit") {
2544
+ exitByCallId.set(event.callId, { present: true, value: event.returnValue });
2545
+ }
2546
+ if (event.type === "function_throw") throwCallIds.add(event.callId);
2547
+ }
2548
+ const state = {
2549
+ instructions: 0,
2550
+ depth: 0,
2551
+ outputBytes: 0,
2552
+ startedAt: Date.now(),
2553
+ recordingCallId: null,
2554
+ omittedCallArgs: /* @__PURE__ */ new Map(),
2555
+ exitByCallId,
2556
+ throwCallIds,
2557
+ childrenByParent,
2558
+ childCursor: /* @__PURE__ */ new Map()
2559
+ };
2560
+ const enterEvents = input.state.events.filter((event) => event.type === "function_enter");
2561
+ const functions = [];
2562
+ for (const enter of enterEvents) {
2563
+ const plan = plansByFunctionId.get(enter.functionId);
2564
+ if (!plan) continue;
2565
+ const callRoots = roots.filter((root) => root.callId === enter.callId);
2566
+ const callFacts = facts.filter((fact) => fact.callId === enter.callId);
2567
+ const evaluated = evaluatePlan(
2568
+ plan,
2569
+ resolveEnterArgs(enter, state.omittedCallArgs),
2570
+ callRoots,
2571
+ callFacts,
2572
+ plansByFunctionId,
2573
+ state,
2574
+ enter.callId,
2575
+ exitByCallId.get(enter.callId),
2576
+ throwCallIds.has(enter.callId)
2577
+ );
2578
+ evaluated.callId = enter.callId;
2579
+ functions.push(evaluated);
2580
+ }
2581
+ return { functions };
2582
+ };
2583
+ var evaluatedValueAtLine = (evaluated, line) => {
2584
+ if (!evaluated) return [];
2585
+ return evaluated.variables.filter((variable) => line == null || variable.availableAtLine <= line).map((variable) => ({ name: variable.name, result: variable.result }));
2586
+ };
2587
+
1445
2588
  // src/instrumentation-manifest/instrumentation-manifest-types.ts
1446
- var INSTRUMENTATION_MANIFEST_SCHEMA_VERSION = 2;
2589
+ var INSTRUMENTATION_MANIFEST_SCHEMA_VERSION = 3;
1447
2590
 
1448
2591
  // src/instrumentation-manifest/upload-instrumentation-manifest.ts
1449
2592
  var uploadInstrumentationManifest = async (options) => {
@@ -1470,15 +2613,29 @@ var uploadInstrumentationManifest = async (options) => {
1470
2613
  };
1471
2614
  export {
1472
2615
  INSTRUMENTATION_MANIFEST_SCHEMA_VERSION,
2616
+ RASPUTIN_WIRE_TAG,
1473
2617
  announceDeploy,
2618
+ capturedValueCompleteness,
1474
2619
  createClient,
1475
2620
  createIngestEvent,
1476
2621
  createSuppression,
1477
2622
  createTransport,
1478
2623
  detectRelease,
2624
+ evaluateRuntimeDerivation,
2625
+ evaluatedValueAtLine,
2626
+ hashInstrumentationManifest,
1479
2627
  isClientEnabled,
2628
+ isRasputinTaggedValue,
2629
+ isRedactedCapturedValue,
2630
+ isSerializerMarker,
1480
2631
  normalizeFrames,
1481
2632
  parseStack,
2633
+ rasputinOmitted,
2634
+ rasputinRedacted,
2635
+ rasputinTagKind,
2636
+ rasputinTruncated,
2637
+ rasputinUnavailable,
2638
+ rasputinUnknown,
1482
2639
  repoRootFrom,
1483
2640
  resetSourceIdentityCache,
1484
2641
  resolveEndpointUrls,