@absolutejs/voice 0.0.22-beta.414 → 0.0.22-beta.416

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.ts CHANGED
@@ -206,6 +206,6 @@ export type { PlivoInboundMessage, PlivoMediaStreamBridge, PlivoMediaStreamBridg
206
206
  export type { VoiceTelephonyCarrierMatrix, VoiceTelephonyCarrierMatrixEntry, VoiceTelephonyCarrierMatrixInput, VoiceTelephonyCarrierMatrixOptions, VoiceTelephonyCarrierMatrixRoutesOptions, VoiceTelephonyCarrierMatrixStatus } from './telephony/matrix';
207
207
  export { shapeTelephonyAssistantText } from './telephony/response';
208
208
  export type { TelephonyResponseShapeMode, TelephonyResponseShapeOptions } from './telephony/response';
209
- export { buildVoiceProofPack, buildVoiceProofPackFromObservabilityExport, createVoiceProofPackArtifacts, createVoiceProofPackOperationsRecordSection, createVoiceProofPackProductionReadinessSection, createVoiceProofPackProviderSloSection, createVoiceProofPackRoutes, createVoiceProofPackSupportBundleSection, renderVoiceProofPackMarkdown, writeVoiceProofPack } from './proofPack';
210
- export type { VoiceProofPack, VoiceProofPackEvidence, VoiceProofPackInput, VoiceProofPackRoutesOptions, VoiceProofPackSection, VoiceProofPackStatus, VoiceProofPackWriteResult } from './proofPack';
209
+ export { buildVoiceProofPack, buildVoiceProofPackFromObservabilityExport, createVoiceProofPackStaleWhileRefreshSource, createVoiceProofPackArtifacts, createVoiceProofPackOperationsRecordSection, createVoiceProofPackProductionReadinessSection, createVoiceProofPackProviderSloSection, createVoiceProofPackRoutes, createVoiceProofPackSupportBundleSection, renderVoiceProofPackMarkdown, writeVoiceProofPack } from './proofPack';
210
+ export type { VoiceProofPack, VoiceProofPackEvidence, VoiceProofPackInput, VoiceProofPackRefreshState, VoiceProofPackRefreshStatus, VoiceProofPackRoutesOptions, VoiceProofPackSection, VoiceProofPackSourceValue, VoiceProofPackStatus, VoiceProofPackStaleWhileRefreshSource, VoiceProofPackStaleWhileRefreshSourceOptions, VoiceProofPackWriteResult } from './proofPack';
211
211
  export * from './types';
package/dist/index.js CHANGED
@@ -39952,6 +39952,16 @@ import { Elysia as Elysia66 } from "elysia";
39952
39952
  import { mkdir as mkdir5 } from "fs/promises";
39953
39953
  import { dirname as dirname3, join as join4 } from "path";
39954
39954
  var toGeneratedAt = (value) => value === undefined ? new Date().toISOString() : typeof value === "number" ? new Date(value).toISOString() : value;
39955
+ var getProofPackMetadata = (proofPack) => {
39956
+ const built = buildVoiceProofPack(proofPack);
39957
+ const generatedAt = built.generatedAt;
39958
+ const generatedAtMs = Date.parse(generatedAt);
39959
+ return {
39960
+ generatedAt,
39961
+ generatedAtMs: Number.isFinite(generatedAtMs) ? generatedAtMs : 0,
39962
+ runId: built.runId
39963
+ };
39964
+ };
39955
39965
  var summarizeProofPackSections = (sections) => {
39956
39966
  let pass = 0;
39957
39967
  let warn = 0;
@@ -40163,6 +40173,98 @@ var buildVoiceProofPack = (input) => {
40163
40173
  summary
40164
40174
  };
40165
40175
  };
40176
+ var createVoiceProofPackStaleWhileRefreshSource = (options) => {
40177
+ const maxAgeMs = options.maxAgeMs ?? 5 * 60000;
40178
+ const now = options.now ?? Date.now;
40179
+ let refreshPromise;
40180
+ let status = {
40181
+ maxAgeMs,
40182
+ refreshing: false,
40183
+ state: "missing"
40184
+ };
40185
+ const updateStatusFromProofPack = (proofPack, refreshing = Boolean(refreshPromise)) => {
40186
+ const metadata = getProofPackMetadata(proofPack);
40187
+ const ageMs = Math.max(0, now() - metadata.generatedAtMs);
40188
+ status = {
40189
+ ageMs,
40190
+ generatedAt: metadata.generatedAt,
40191
+ lastRefreshCompletedAt: status.lastRefreshCompletedAt,
40192
+ lastRefreshStartedAt: status.lastRefreshStartedAt,
40193
+ maxAgeMs,
40194
+ refreshing,
40195
+ runId: metadata.runId,
40196
+ state: refreshing ? "refreshing" : ageMs <= maxAgeMs ? "fresh" : "stale"
40197
+ };
40198
+ return { ageMs, metadata };
40199
+ };
40200
+ const refresh = async () => {
40201
+ const refreshed = await options.refresh();
40202
+ const proofPack = refreshed ?? await options.read();
40203
+ updateStatusFromProofPack(proofPack, false);
40204
+ status = {
40205
+ ...status,
40206
+ lastRefreshCompletedAt: now(),
40207
+ lastRefreshStartedAt: status.lastRefreshStartedAt,
40208
+ refreshing: false,
40209
+ state: "fresh"
40210
+ };
40211
+ return proofPack;
40212
+ };
40213
+ const startRefresh = () => {
40214
+ if (!refreshPromise) {
40215
+ status = {
40216
+ ...status,
40217
+ lastRefreshStartedAt: now(),
40218
+ refreshing: true,
40219
+ state: "refreshing"
40220
+ };
40221
+ }
40222
+ refreshPromise ??= refresh().finally(() => {
40223
+ refreshPromise = undefined;
40224
+ });
40225
+ return refreshPromise;
40226
+ };
40227
+ const source = async () => {
40228
+ let current;
40229
+ try {
40230
+ current = await options.read();
40231
+ } catch (error) {
40232
+ status = {
40233
+ ...status,
40234
+ error: error instanceof Error ? error.message : String(error),
40235
+ refreshing: Boolean(refreshPromise),
40236
+ state: refreshPromise ? "refreshing" : "missing"
40237
+ };
40238
+ return startRefresh().catch((refreshError) => {
40239
+ status = {
40240
+ ...status,
40241
+ error: refreshError instanceof Error ? refreshError.message : String(refreshError),
40242
+ lastRefreshCompletedAt: now(),
40243
+ refreshing: false,
40244
+ state: "failed"
40245
+ };
40246
+ throw refreshError;
40247
+ });
40248
+ }
40249
+ const { ageMs } = updateStatusFromProofPack(current);
40250
+ if (ageMs <= maxAgeMs) {
40251
+ return current;
40252
+ }
40253
+ startRefresh().catch((error) => {
40254
+ status = {
40255
+ ...status,
40256
+ error: error instanceof Error ? error.message : String(error),
40257
+ lastRefreshCompletedAt: now(),
40258
+ refreshing: false,
40259
+ state: "failed"
40260
+ };
40261
+ options.onRefreshError?.(error);
40262
+ });
40263
+ return current;
40264
+ };
40265
+ source.getStatus = () => status;
40266
+ return source;
40267
+ };
40166
40268
  var buildVoiceProofPackFromObservabilityExport = (report, input = {}) => buildVoiceProofPack({
40167
40269
  ...input,
40168
40270
  artifacts: report.artifacts,
@@ -40725,6 +40827,7 @@ export {
40725
40827
  createVoiceProofTrendRecommendationRoutes,
40726
40828
  createVoiceProofTraceStore,
40727
40829
  createVoiceProofPackSupportBundleSection,
40830
+ createVoiceProofPackStaleWhileRefreshSource,
40728
40831
  createVoiceProofPackRoutes,
40729
40832
  createVoiceProofPackProviderSloSection,
40730
40833
  createVoiceProofPackProductionReadinessSection,
@@ -53,12 +53,35 @@ export type VoiceProofPackWriteResult = {
53
53
  markdownPath: string;
54
54
  proofPack: VoiceProofPack;
55
55
  };
56
+ export type VoiceProofPackSourceValue = VoiceProofPack | VoiceProofPackInput;
57
+ export type VoiceProofPackStaleWhileRefreshSourceOptions = {
58
+ maxAgeMs?: number;
59
+ now?: () => number;
60
+ onRefreshError?: (error: unknown) => void;
61
+ read: () => VoiceProofPackSourceValue | Promise<VoiceProofPackSourceValue>;
62
+ refresh: () => VoiceProofPackSourceValue | void | Promise<VoiceProofPackSourceValue | void>;
63
+ };
64
+ export type VoiceProofPackRefreshState = 'failed' | 'fresh' | 'missing' | 'refreshing' | 'stale';
65
+ export type VoiceProofPackRefreshStatus = {
66
+ ageMs?: number;
67
+ error?: string;
68
+ generatedAt?: string;
69
+ lastRefreshCompletedAt?: number;
70
+ lastRefreshStartedAt?: number;
71
+ maxAgeMs: number;
72
+ refreshing: boolean;
73
+ runId?: string;
74
+ state: VoiceProofPackRefreshState;
75
+ };
76
+ export type VoiceProofPackStaleWhileRefreshSource = ((...args: []) => Promise<VoiceProofPackSourceValue>) & {
77
+ getStatus: () => VoiceProofPackRefreshStatus;
78
+ };
56
79
  export type VoiceProofPackRoutesOptions = {
57
80
  headers?: HeadersInit;
58
81
  jsonPath?: false | string;
59
82
  markdownPath?: false | string;
60
83
  name?: string;
61
- source: VoiceProofPack | VoiceProofPackInput | (() => VoiceProofPack | VoiceProofPackInput | Promise<VoiceProofPack | VoiceProofPackInput>);
84
+ source: VoiceProofPackSourceValue | (() => VoiceProofPackSourceValue | Promise<VoiceProofPackSourceValue>);
62
85
  };
63
86
  export declare const createVoiceProofPackProviderSloSection: (report: VoiceProviderSloReport, options?: {
64
87
  href?: string;
@@ -77,6 +100,7 @@ export declare const createVoiceProofPackSupportBundleSection: (input: {
77
100
  title?: string;
78
101
  }) => VoiceProofPackSection;
79
102
  export declare const buildVoiceProofPack: (input: VoiceProofPackInput | VoiceProofPack) => VoiceProofPack;
103
+ export declare const createVoiceProofPackStaleWhileRefreshSource: (options: VoiceProofPackStaleWhileRefreshSourceOptions) => VoiceProofPackStaleWhileRefreshSource;
80
104
  export declare const buildVoiceProofPackFromObservabilityExport: (report: VoiceObservabilityExportReport, input?: Omit<VoiceProofPackInput, "artifacts" | "sections">) => VoiceProofPack;
81
105
  export declare const renderVoiceProofPackMarkdown: (proofPack: VoiceProofPack) => string;
82
106
  export declare const writeVoiceProofPack: (input: VoiceProofPackInput | VoiceProofPack, options?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/voice",
3
- "version": "0.0.22-beta.414",
3
+ "version": "0.0.22-beta.416",
4
4
  "description": "Voice primitives and Elysia plugin for AbsoluteJS",
5
5
  "repository": {
6
6
  "type": "git",