@lunora/do 1.0.0-alpha.41 → 1.0.0-alpha.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -2425,8 +2425,11 @@ interface TracerDeps {
2425
2425
  * **custom span**, so it nests inside CF's native binding/fetch/handler trace
2426
2426
  * tree on the hosted path. This only ADDS a CF-side span — the recorded
2427
2427
  * {@link SpanEvent} (our `SpanBuffer`/`otlpSink`) is untouched and remains the
2428
- * source of truth plus the local studio waterfall. See {@link createTracer}
2429
- * for the double-export and Durable-Object async-context caveats.
2428
+ * source of truth plus the local studio waterfall. The `enterSpan` call itself
2429
+ * is now workerd-validated as available and side-effect-free inside a Durable
2430
+ * Object; CF's exported parent-linking under sampling remains unverified. See
2431
+ * {@link createTracer} for the double-export and Durable-Object async-context
2432
+ * caveats.
2430
2433
  */
2431
2434
  fuseCloudflareSpans?: boolean;
2432
2435
  /** Hand a finished span to the buffer + sink. */
@@ -2488,12 +2491,22 @@ interface MetricsDeps {
2488
2491
  * pipelines — an intentional, documented trade the operator opts into, not a
2489
2492
  * default.
2490
2493
  *
2491
- * **DO async-context caveat.** `tracing.enterSpan`'s parent-linking inside Durable
2492
- * Objects is unverified upstream, so this is capability-probed: an
2493
- * absent/undefined `tracing`, a missing `enterSpan`, or an off-CF/unsampled run
2494
- * all resolve to `undefined` and the bridge is a total no-op — exact prior
2495
- * behavior. If CF's ambient-span linkage misbehaves in a DO, the worst case is a
2496
- * mis-parented CF span; our own recorded waterfall is unaffected.
2494
+ * **DO async-context caveat (EXPERIMENTAL, partially workerd-validated).**
2495
+ * `tracing.enterSpan` is now confirmed to EXIST and RUN inside a real Durable
2496
+ * Object under `@cloudflare/vitest-pool-workers` (see
2497
+ * `__tests__/workerd/context-telemetry-cf-bridge.workerd.test.ts`): it resolves
2498
+ * from `cloudflare:workers`, its callback executes and returns the body value
2499
+ * without throwing, `span.isTraced` is a real boolean, and — the key additive
2500
+ * guarantee — our recorded {@link SpanEvent} tree (parent/child via the threaded
2501
+ * `parentSpanId`) is byte-for-byte identical with the bridge on vs off. What that
2502
+ * harness CANNOT prove is CF's own *exported* parent-linking: with no trace head
2503
+ * attached the run is unsampled (`isTraced === false`), so CF records nothing and
2504
+ * its span tree is not introspectable. So `enterSpan`'s ambient-span parent-linking
2505
+ * inside a DO stays unverified upstream, and this remains capability-probed: an
2506
+ * absent/undefined `tracing`, a missing `enterSpan`, or an off-CF/unsampled run all
2507
+ * resolve to `undefined`/no-op — exact prior behavior. If CF's ambient-span linkage
2508
+ * misbehaves in a DO, the worst case is a mis-parented CF span; our own recorded
2509
+ * waterfall is unaffected.
2497
2510
  */
2498
2511
  declare const createTracer: (deps: TracerDeps) => ContextTracer;
2499
2512
  /**
@@ -4407,7 +4420,10 @@ interface TelemetrySink {
4407
4420
  * tree on the hosted path — capability-probed, and a safe no-op off-CF / on an
4408
4421
  * older compat date / when unsampled. This only ADDS a CF-side span; the
4409
4422
  * `onSpan` event below (our `SpanBuffer`/`otlpSink`) is unchanged and stays the
4410
- * source of truth. Mirror of `@lunora/runtime`'s `ObservabilitySink`
4423
+ * source of truth. The bridge is now workerd-validated as available and
4424
+ * side-effect-free inside a real DO (our recorded spans stay intact); CF's
4425
+ * exported parent-linking under sampling is still unverified, so it stays
4426
+ * EXPERIMENTAL. Mirror of `@lunora/runtime`'s `ObservabilitySink`
4411
4427
  * `fuseCloudflareTraces`; see {@link createTracer} for the double-export caveat.
4412
4428
  */
4413
4429
  fuseCloudflareTraces?: boolean;
package/dist/index.d.ts CHANGED
@@ -2425,8 +2425,11 @@ interface TracerDeps {
2425
2425
  * **custom span**, so it nests inside CF's native binding/fetch/handler trace
2426
2426
  * tree on the hosted path. This only ADDS a CF-side span — the recorded
2427
2427
  * {@link SpanEvent} (our `SpanBuffer`/`otlpSink`) is untouched and remains the
2428
- * source of truth plus the local studio waterfall. See {@link createTracer}
2429
- * for the double-export and Durable-Object async-context caveats.
2428
+ * source of truth plus the local studio waterfall. The `enterSpan` call itself
2429
+ * is now workerd-validated as available and side-effect-free inside a Durable
2430
+ * Object; CF's exported parent-linking under sampling remains unverified. See
2431
+ * {@link createTracer} for the double-export and Durable-Object async-context
2432
+ * caveats.
2430
2433
  */
2431
2434
  fuseCloudflareSpans?: boolean;
2432
2435
  /** Hand a finished span to the buffer + sink. */
@@ -2488,12 +2491,22 @@ interface MetricsDeps {
2488
2491
  * pipelines — an intentional, documented trade the operator opts into, not a
2489
2492
  * default.
2490
2493
  *
2491
- * **DO async-context caveat.** `tracing.enterSpan`'s parent-linking inside Durable
2492
- * Objects is unverified upstream, so this is capability-probed: an
2493
- * absent/undefined `tracing`, a missing `enterSpan`, or an off-CF/unsampled run
2494
- * all resolve to `undefined` and the bridge is a total no-op — exact prior
2495
- * behavior. If CF's ambient-span linkage misbehaves in a DO, the worst case is a
2496
- * mis-parented CF span; our own recorded waterfall is unaffected.
2494
+ * **DO async-context caveat (EXPERIMENTAL, partially workerd-validated).**
2495
+ * `tracing.enterSpan` is now confirmed to EXIST and RUN inside a real Durable
2496
+ * Object under `@cloudflare/vitest-pool-workers` (see
2497
+ * `__tests__/workerd/context-telemetry-cf-bridge.workerd.test.ts`): it resolves
2498
+ * from `cloudflare:workers`, its callback executes and returns the body value
2499
+ * without throwing, `span.isTraced` is a real boolean, and — the key additive
2500
+ * guarantee — our recorded {@link SpanEvent} tree (parent/child via the threaded
2501
+ * `parentSpanId`) is byte-for-byte identical with the bridge on vs off. What that
2502
+ * harness CANNOT prove is CF's own *exported* parent-linking: with no trace head
2503
+ * attached the run is unsampled (`isTraced === false`), so CF records nothing and
2504
+ * its span tree is not introspectable. So `enterSpan`'s ambient-span parent-linking
2505
+ * inside a DO stays unverified upstream, and this remains capability-probed: an
2506
+ * absent/undefined `tracing`, a missing `enterSpan`, or an off-CF/unsampled run all
2507
+ * resolve to `undefined`/no-op — exact prior behavior. If CF's ambient-span linkage
2508
+ * misbehaves in a DO, the worst case is a mis-parented CF span; our own recorded
2509
+ * waterfall is unaffected.
2497
2510
  */
2498
2511
  declare const createTracer: (deps: TracerDeps) => ContextTracer;
2499
2512
  /**
@@ -4407,7 +4420,10 @@ interface TelemetrySink {
4407
4420
  * tree on the hosted path — capability-probed, and a safe no-op off-CF / on an
4408
4421
  * older compat date / when unsampled. This only ADDS a CF-side span; the
4409
4422
  * `onSpan` event below (our `SpanBuffer`/`otlpSink`) is unchanged and stays the
4410
- * source of truth. Mirror of `@lunora/runtime`'s `ObservabilitySink`
4423
+ * source of truth. The bridge is now workerd-validated as available and
4424
+ * side-effect-free inside a real DO (our recorded spans stay intact); CF's
4425
+ * exported parent-linking under sampling is still unverified, so it stays
4426
+ * EXPERIMENTAL. Mirror of `@lunora/runtime`'s `ObservabilitySink`
4411
4427
  * `fuseCloudflareTraces`; see {@link createTracer} for the double-export caveat.
4412
4428
  */
4413
4429
  fuseCloudflareTraces?: boolean;
package/dist/index.mjs CHANGED
@@ -28,7 +28,7 @@ export { RLS_UNWRAP_SYMBOL, RlsRequiredError, guardWriter } from './packem_share
28
28
  export { buildFtsMatch, ftsTableName, scoreDocument, stringifySearchText, tokenizeSearch } from './packem_shared/buildFtsMatch-BLEMawrp.mjs';
29
29
  export { M as MIN_ADMIN_TOKEN_LENGTH, a as MIN_AUTH_SECRET_LENGTH, b as buildSecurityAudit } from './packem_shared/security-audit-CucgBice.mjs';
30
30
  export { SESSION_DO_TTL_DEFAULT, SessionDO } from './packem_shared/SESSION_DO_TTL_DEFAULT-BnSKgVO4.mjs';
31
- export { ROOT_DO_SIZE_WARN_BYTES, ROOT_SHARD_NAME, ShardDO } from './packem_shared/ROOT_DO_SIZE_WARN_BYTES-B4Cpm7Qv.mjs';
31
+ export { ROOT_DO_SIZE_WARN_BYTES, ROOT_SHARD_NAME, ShardDO } from './packem_shared/ROOT_DO_SIZE_WARN_BYTES-B_zt4RQE.mjs';
32
32
  export { SHARD_REGISTRY_DO_NAME, ShardRegistryDO } from './packem_shared/SHARD_REGISTRY_DO_NAME-D99roc-r.mjs';
33
33
  export { MAX_SQL_ROWS, assertReadonly, runReadonlySql } from './packem_shared/MAX_SQL_ROWS-iFAA8FbD.mjs';
34
34
  export { createSystemReader } from './packem_shared/createSystemReader-D12eNH13.mjs';
@@ -356,7 +356,11 @@ const runSql$3 = (sql, query, ...parameters) => {
356
356
  return runner.call(sql, query, ...parameters);
357
357
  };
358
358
  const bucketFloor = (ts) => Math.floor(ts / METRIC_HISTORY_BUCKET_MS) * METRIC_HISTORY_BUCKET_MS;
359
+ const ensuredHandles = /* @__PURE__ */ new WeakSet();
359
360
  const ensureMetricHistoryTable = (sql) => {
361
+ if (ensuredHandles.has(sql)) {
362
+ return;
363
+ }
360
364
  runSql$3(
361
365
  sql,
362
366
  `CREATE TABLE IF NOT EXISTS "${METRIC_HISTORY_TABLE}" (
@@ -377,12 +381,25 @@ const ensureMetricHistoryTable = (sql) => {
377
381
  PRIMARY KEY (series_key, bucket_ms)
378
382
  )`
379
383
  );
384
+ ensuredHandles.add(sql);
385
+ };
386
+ const KNOWN_BUCKETS_CAP = 4096;
387
+ const knownBuckets = /* @__PURE__ */ new WeakMap();
388
+ const knownBucketsFor = (sql) => {
389
+ let set = knownBuckets.get(sql);
390
+ if (set === void 0) {
391
+ set = /* @__PURE__ */ new Set();
392
+ knownBuckets.set(sql, set);
393
+ }
394
+ return set;
380
395
  };
381
396
  const recordMetricHistory = (sql, event, exemplarTraceId) => {
382
397
  ensureMetricHistoryTable(sql);
383
398
  const key = metricSeriesKey(event);
384
399
  const bucket = bucketFloor(event.ts);
385
- const bucketExists = runSql$3(sql, `SELECT 1 AS c FROM "${METRIC_HISTORY_TABLE}" WHERE series_key = ? AND bucket_ms = ? LIMIT 1`, key, bucket).toArray().length > 0;
400
+ const cache = knownBucketsFor(sql);
401
+ const cacheKey = `${key}\0${bucket.toString()}`;
402
+ const bucketExists = cache.has(cacheKey) || runSql$3(sql, `SELECT 1 AS c FROM "${METRIC_HISTORY_TABLE}" WHERE series_key = ? AND bucket_ms = ? LIMIT 1`, key, bucket).toArray().length > 0;
386
403
  if (!bucketExists) {
387
404
  const seriesTracked = runSql$3(sql, `SELECT 1 AS c FROM "${METRIC_HISTORY_TABLE}" WHERE series_key = ? LIMIT 1`, key).toArray().length > 0;
388
405
  if (!seriesTracked) {
@@ -434,6 +451,12 @@ const recordMetricHistory = (sql, event, exemplarTraceId) => {
434
451
  key
435
452
  );
436
453
  }
454
+ if (bucketExists && !cache.has(cacheKey)) {
455
+ if (cache.size >= KNOWN_BUCKETS_CAP) {
456
+ cache.clear();
457
+ }
458
+ cache.add(cacheKey);
459
+ }
437
460
  };
438
461
  const parseAttributes = (raw) => {
439
462
  if (raw === "" || raw === "{}") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/do",
3
- "version": "1.0.0-alpha.41",
3
+ "version": "1.0.0-alpha.42",
4
4
  "description": "Lunora Durable Objects: ShardDO (SQLite, OCC, hibernated WebSocket subscriptions) and SessionDO",
5
5
  "keywords": [
6
6
  "cloudflare",