progressive-zod 1.2.0 → 1.3.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.
- package/.claude/commands/instrument.md +12 -1
- package/README.md +11 -1
- package/dist/cli/index.js +105 -47
- package/dist/client.cjs +49 -83
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +2 -2
- package/dist/client.d.ts +2 -2
- package/dist/client.js +49 -73
- package/dist/client.js.map +1 -1
- package/dist/index.cjs +136 -74
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +136 -74
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -35,6 +35,13 @@ var amplitude_exports = {};
|
|
|
35
35
|
__export(amplitude_exports, {
|
|
36
36
|
AmplitudeStorage: () => AmplitudeStorage
|
|
37
37
|
});
|
|
38
|
+
function flattenToString(value) {
|
|
39
|
+
if (value === null || value === void 0) return String(value);
|
|
40
|
+
if (typeof value !== "object") return String(value);
|
|
41
|
+
if (Array.isArray(value)) return value.map(String).join(", ");
|
|
42
|
+
const entries = Object.entries(value);
|
|
43
|
+
return entries.map(([k, v]) => `${k}=${JSON.stringify(v)}`).join("; ");
|
|
44
|
+
}
|
|
38
45
|
var AmplitudeStorage;
|
|
39
46
|
var init_amplitude = __esm({
|
|
40
47
|
"src/storage/amplitude.ts"() {
|
|
@@ -52,17 +59,37 @@ var init_amplitude = __esm({
|
|
|
52
59
|
}
|
|
53
60
|
addViolation(_name, _violation) {
|
|
54
61
|
}
|
|
55
|
-
incrConform(name) {
|
|
62
|
+
incrConform(name, _sample) {
|
|
56
63
|
this.client.track(
|
|
57
64
|
"pzod:type_checked",
|
|
58
65
|
{ type_name: name, result: "conform" },
|
|
59
66
|
{ device_id: this.deviceId }
|
|
60
67
|
);
|
|
61
68
|
}
|
|
62
|
-
incrViolate(name) {
|
|
69
|
+
incrViolate(name, sample, errors) {
|
|
70
|
+
const properties = {
|
|
71
|
+
type_name: name,
|
|
72
|
+
result: "violate"
|
|
73
|
+
};
|
|
74
|
+
if (sample) {
|
|
75
|
+
try {
|
|
76
|
+
const parsed = JSON.parse(sample);
|
|
77
|
+
properties.sample_type = typeof parsed;
|
|
78
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
79
|
+
properties.field_count = Object.keys(parsed).length;
|
|
80
|
+
}
|
|
81
|
+
properties.sample_preview = flattenToString(parsed).slice(0, 256);
|
|
82
|
+
} catch {
|
|
83
|
+
properties.sample_type = "unknown";
|
|
84
|
+
properties.sample_preview = sample.slice(0, 256);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (errors) {
|
|
88
|
+
properties.validation_errors = errors.slice(0, 1024);
|
|
89
|
+
}
|
|
63
90
|
this.client.track(
|
|
64
91
|
"pzod:type_checked",
|
|
65
|
-
|
|
92
|
+
properties,
|
|
66
93
|
{ device_id: this.deviceId }
|
|
67
94
|
);
|
|
68
95
|
}
|
|
@@ -199,22 +226,14 @@ __export(index_exports, {
|
|
|
199
226
|
module.exports = __toCommonJS(index_exports);
|
|
200
227
|
|
|
201
228
|
// src/storage/memory.ts
|
|
202
|
-
var fs = __toESM(require("fs"), 1);
|
|
203
|
-
var path = __toESM(require("path"), 1);
|
|
204
229
|
var MemoryStorage = class {
|
|
205
230
|
names = /* @__PURE__ */ new Set();
|
|
206
231
|
data = /* @__PURE__ */ new Map();
|
|
207
232
|
maxSamples;
|
|
208
233
|
maxViolations;
|
|
209
|
-
dataDir;
|
|
210
|
-
flushTimer;
|
|
211
234
|
constructor(config = {}) {
|
|
212
235
|
this.maxSamples = config.maxSamples ?? 1e3;
|
|
213
236
|
this.maxViolations = config.maxViolations ?? 1e3;
|
|
214
|
-
this.dataDir = config.dataDir;
|
|
215
|
-
if (this.dataDir) {
|
|
216
|
-
this.loadFromDisk();
|
|
217
|
-
}
|
|
218
237
|
}
|
|
219
238
|
getOrCreate(name) {
|
|
220
239
|
let entry = this.data.get(name);
|
|
@@ -226,7 +245,6 @@ var MemoryStorage = class {
|
|
|
226
245
|
}
|
|
227
246
|
addName(name) {
|
|
228
247
|
this.names.add(name);
|
|
229
|
-
this.schedulePersist();
|
|
230
248
|
}
|
|
231
249
|
addSample(name, sample) {
|
|
232
250
|
const entry = this.getOrCreate(name);
|
|
@@ -234,7 +252,6 @@ var MemoryStorage = class {
|
|
|
234
252
|
if (entry.samples.length > this.maxSamples) {
|
|
235
253
|
entry.samples.length = this.maxSamples;
|
|
236
254
|
}
|
|
237
|
-
this.schedulePersist();
|
|
238
255
|
}
|
|
239
256
|
addViolation(name, violation) {
|
|
240
257
|
const entry = this.getOrCreate(name);
|
|
@@ -242,15 +259,12 @@ var MemoryStorage = class {
|
|
|
242
259
|
if (entry.violations.length > this.maxViolations) {
|
|
243
260
|
entry.violations.length = this.maxViolations;
|
|
244
261
|
}
|
|
245
|
-
this.schedulePersist();
|
|
246
262
|
}
|
|
247
263
|
incrConform(name) {
|
|
248
264
|
this.getOrCreate(name).conform++;
|
|
249
|
-
this.schedulePersist();
|
|
250
265
|
}
|
|
251
266
|
incrViolate(name) {
|
|
252
267
|
this.getOrCreate(name).violate++;
|
|
253
|
-
this.schedulePersist();
|
|
254
268
|
}
|
|
255
269
|
getNames() {
|
|
256
270
|
return [...this.names].sort();
|
|
@@ -266,54 +280,6 @@ var MemoryStorage = class {
|
|
|
266
280
|
return { conform: entry.conform, violate: entry.violate };
|
|
267
281
|
}
|
|
268
282
|
disconnect() {
|
|
269
|
-
if (this.flushTimer) {
|
|
270
|
-
clearTimeout(this.flushTimer);
|
|
271
|
-
this.flushTimer = void 0;
|
|
272
|
-
}
|
|
273
|
-
if (this.dataDir) {
|
|
274
|
-
this.persistToDisk();
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
schedulePersist() {
|
|
278
|
-
if (!this.dataDir || this.flushTimer) return;
|
|
279
|
-
this.flushTimer = setTimeout(() => {
|
|
280
|
-
this.flushTimer = void 0;
|
|
281
|
-
this.persistToDisk();
|
|
282
|
-
}, 500);
|
|
283
|
-
}
|
|
284
|
-
persistToDisk() {
|
|
285
|
-
if (!this.dataDir) return;
|
|
286
|
-
try {
|
|
287
|
-
fs.mkdirSync(this.dataDir, { recursive: true });
|
|
288
|
-
const snapshot = {
|
|
289
|
-
names: [...this.names],
|
|
290
|
-
types: Object.fromEntries(this.data)
|
|
291
|
-
};
|
|
292
|
-
fs.writeFileSync(
|
|
293
|
-
path.join(this.dataDir, "data.json"),
|
|
294
|
-
JSON.stringify(snapshot, null, 2)
|
|
295
|
-
);
|
|
296
|
-
} catch {
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
loadFromDisk() {
|
|
300
|
-
if (!this.dataDir) return;
|
|
301
|
-
try {
|
|
302
|
-
const raw = fs.readFileSync(
|
|
303
|
-
path.join(this.dataDir, "data.json"),
|
|
304
|
-
"utf-8"
|
|
305
|
-
);
|
|
306
|
-
const snapshot = JSON.parse(raw);
|
|
307
|
-
if (Array.isArray(snapshot.names)) {
|
|
308
|
-
for (const n of snapshot.names) this.names.add(n);
|
|
309
|
-
}
|
|
310
|
-
if (snapshot.types && typeof snapshot.types === "object") {
|
|
311
|
-
for (const [key, val] of Object.entries(snapshot.types)) {
|
|
312
|
-
this.data.set(key, val);
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
} catch {
|
|
316
|
-
}
|
|
317
283
|
}
|
|
318
284
|
};
|
|
319
285
|
|
|
@@ -331,14 +297,20 @@ function configure(config) {
|
|
|
331
297
|
currentStorage = null;
|
|
332
298
|
}
|
|
333
299
|
}
|
|
300
|
+
function env(key) {
|
|
301
|
+
if (typeof process !== "undefined" && process.env) {
|
|
302
|
+
return process.env[key];
|
|
303
|
+
}
|
|
304
|
+
return void 0;
|
|
305
|
+
}
|
|
334
306
|
function getConfig() {
|
|
335
307
|
return {
|
|
336
|
-
storage: currentConfig.storage ??
|
|
337
|
-
redisUrl: currentConfig.redisUrl ??
|
|
338
|
-
keyPrefix: currentConfig.keyPrefix ??
|
|
339
|
-
maxViolations: currentConfig.maxViolations ?? parseInt(
|
|
340
|
-
maxSamples: currentConfig.maxSamples ?? parseInt(
|
|
341
|
-
dataDir: currentConfig.dataDir ??
|
|
308
|
+
storage: currentConfig.storage ?? env("PROGRESSIVE_ZOD_STORAGE") ?? "memory",
|
|
309
|
+
redisUrl: currentConfig.redisUrl ?? env("PROGRESSIVE_ZOD_REDIS_URL"),
|
|
310
|
+
keyPrefix: currentConfig.keyPrefix ?? env("PROGRESSIVE_ZOD_KEY_PREFIX") ?? "pzod:",
|
|
311
|
+
maxViolations: currentConfig.maxViolations ?? parseInt(env("PROGRESSIVE_ZOD_MAX_VIOLATIONS") ?? "1000", 10),
|
|
312
|
+
maxSamples: currentConfig.maxSamples ?? parseInt(env("PROGRESSIVE_ZOD_MAX_SAMPLES") ?? "1000", 10),
|
|
313
|
+
dataDir: currentConfig.dataDir ?? env("PROGRESSIVE_ZOD_DATA_DIR")
|
|
342
314
|
};
|
|
343
315
|
}
|
|
344
316
|
async function getStorage() {
|
|
@@ -460,13 +432,17 @@ var BatchProcessor = class {
|
|
|
460
432
|
if (obs.schema) {
|
|
461
433
|
const result = obs.schema.safeParse(JSON.parse(obs.serialized));
|
|
462
434
|
if (result.success) {
|
|
463
|
-
await storage.incrConform(obs.name);
|
|
435
|
+
await storage.incrConform(obs.name, obs.serialized);
|
|
464
436
|
} else {
|
|
465
|
-
|
|
437
|
+
const errors = result.error.issues.map((i) => {
|
|
438
|
+
const path2 = i.path.length > 0 ? i.path.join(".") : "(root)";
|
|
439
|
+
return `${path2}: ${i.message}`;
|
|
440
|
+
}).join("; ");
|
|
441
|
+
await storage.incrViolate(obs.name, obs.serialized, errors);
|
|
466
442
|
await storage.addViolation(obs.name, obs.serialized);
|
|
467
443
|
}
|
|
468
444
|
} else {
|
|
469
|
-
await storage.incrViolate(obs.name);
|
|
445
|
+
await storage.incrViolate(obs.name, obs.serialized, "no schema defined");
|
|
470
446
|
await storage.addViolation(obs.name, obs.serialized);
|
|
471
447
|
}
|
|
472
448
|
}
|
|
@@ -507,6 +483,91 @@ function progressive(name, schema) {
|
|
|
507
483
|
};
|
|
508
484
|
}
|
|
509
485
|
|
|
486
|
+
// src/storage/memory-server.ts
|
|
487
|
+
var fs = __toESM(require("fs"), 1);
|
|
488
|
+
var path = __toESM(require("path"), 1);
|
|
489
|
+
var PersistentMemoryStorage = class extends MemoryStorage {
|
|
490
|
+
dataDir;
|
|
491
|
+
flushTimer;
|
|
492
|
+
constructor(config = {}) {
|
|
493
|
+
super(config);
|
|
494
|
+
this.dataDir = config.dataDir;
|
|
495
|
+
if (this.dataDir) {
|
|
496
|
+
this.loadFromDisk();
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
addName(name) {
|
|
500
|
+
super.addName(name);
|
|
501
|
+
this.schedulePersist();
|
|
502
|
+
}
|
|
503
|
+
addSample(name, sample) {
|
|
504
|
+
super.addSample(name, sample);
|
|
505
|
+
this.schedulePersist();
|
|
506
|
+
}
|
|
507
|
+
addViolation(name, violation) {
|
|
508
|
+
super.addViolation(name, violation);
|
|
509
|
+
this.schedulePersist();
|
|
510
|
+
}
|
|
511
|
+
incrConform(name) {
|
|
512
|
+
super.incrConform(name);
|
|
513
|
+
this.schedulePersist();
|
|
514
|
+
}
|
|
515
|
+
incrViolate(name) {
|
|
516
|
+
super.incrViolate(name);
|
|
517
|
+
this.schedulePersist();
|
|
518
|
+
}
|
|
519
|
+
disconnect() {
|
|
520
|
+
if (this.flushTimer) {
|
|
521
|
+
clearTimeout(this.flushTimer);
|
|
522
|
+
this.flushTimer = void 0;
|
|
523
|
+
}
|
|
524
|
+
if (this.dataDir) {
|
|
525
|
+
this.persistToDisk();
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
schedulePersist() {
|
|
529
|
+
if (!this.dataDir || this.flushTimer) return;
|
|
530
|
+
this.flushTimer = setTimeout(() => {
|
|
531
|
+
this.flushTimer = void 0;
|
|
532
|
+
this.persistToDisk();
|
|
533
|
+
}, 500);
|
|
534
|
+
}
|
|
535
|
+
persistToDisk() {
|
|
536
|
+
if (!this.dataDir) return;
|
|
537
|
+
try {
|
|
538
|
+
fs.mkdirSync(this.dataDir, { recursive: true });
|
|
539
|
+
const snapshot = {
|
|
540
|
+
names: [...this.names],
|
|
541
|
+
types: Object.fromEntries(this.data)
|
|
542
|
+
};
|
|
543
|
+
fs.writeFileSync(
|
|
544
|
+
path.join(this.dataDir, "data.json"),
|
|
545
|
+
JSON.stringify(snapshot, null, 2)
|
|
546
|
+
);
|
|
547
|
+
} catch {
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
loadFromDisk() {
|
|
551
|
+
if (!this.dataDir) return;
|
|
552
|
+
try {
|
|
553
|
+
const raw = fs.readFileSync(
|
|
554
|
+
path.join(this.dataDir, "data.json"),
|
|
555
|
+
"utf-8"
|
|
556
|
+
);
|
|
557
|
+
const snapshot = JSON.parse(raw);
|
|
558
|
+
if (Array.isArray(snapshot.names)) {
|
|
559
|
+
for (const n of snapshot.names) this.names.add(n);
|
|
560
|
+
}
|
|
561
|
+
if (snapshot.types && typeof snapshot.types === "object") {
|
|
562
|
+
for (const [key, val] of Object.entries(snapshot.types)) {
|
|
563
|
+
this.data.set(key, val);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
} catch {
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
|
|
510
571
|
// src/storage/index.ts
|
|
511
572
|
_setStorageFactory(async (config, userConfig) => {
|
|
512
573
|
if (config.storage === "amplitude") {
|
|
@@ -521,7 +582,8 @@ _setStorageFactory(async (config, userConfig) => {
|
|
|
521
582
|
const { RedisStorage: RedisStorage2 } = await Promise.resolve().then(() => (init_redis(), redis_exports));
|
|
522
583
|
return new RedisStorage2(config);
|
|
523
584
|
}
|
|
524
|
-
|
|
585
|
+
const serverConfig = { ...config, dataDir: config.dataDir ?? ".progressive-zod" };
|
|
586
|
+
return new PersistentMemoryStorage(serverConfig);
|
|
525
587
|
});
|
|
526
588
|
|
|
527
589
|
// src/infer-schema.ts
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/storage/amplitude.ts","../src/storage/redis.ts","../src/index.ts","../src/storage/memory.ts","../src/storage/resolve.ts","../src/batch-processor.ts","../src/progressive.ts","../src/storage/index.ts","../src/infer-schema.ts","../src/schema-to-code.ts"],"sourcesContent":["import type { ProgressiveConfig, StorageBackend } from \"../types.js\";\n\n/**\n * Minimal interface for an Amplitude client.\n * Compatible with @amplitude/analytics-node's `track()` signature.\n * Pass an instance initialized with your observability project's API key\n * (separate from your main product analytics project).\n */\nexport interface AmplitudeClient {\n track(\n eventName: string,\n eventProperties?: Record<string, unknown>,\n options?: { user_id?: string; device_id?: string },\n ): void;\n}\n\n/**\n * Amplitude storage backend for progressive-zod.\n *\n * Sends a single event per type check:\n *\n * \"pzod:type_checked\"\n * - type_name: string — the boundary name passed to progressive()\n * - result: \"conform\" | \"violate\"\n * - sample_type: string — JS typeof the observed value (violate only)\n * - field_count: number — number of top-level keys (violate only, objects)\n * - sample_preview: string — first 256 chars of JSON (violate only)\n *\n * Read methods (getNames, getSamples, etc.) are no-ops — use the\n * Amplitude dashboard to query your data.\n */\nexport class AmplitudeStorage implements StorageBackend {\n private readonly client: AmplitudeClient;\n private readonly deviceId: string;\n\n constructor(\n client: AmplitudeClient,\n config: ProgressiveConfig,\n ) {\n this.client = client;\n // Use a stable device_id so Amplitude groups events from this service\n this.deviceId = `pzod:${config.keyPrefix ?? \"default\"}`;\n }\n\n addName(_name: string): void {\n // No-op: we only track type checks\n }\n\n addSample(_name: string, _sample: string): void {\n // No-op: we only track type checks\n }\n\n addViolation(_name: string, _violation: string): void {\n // No-op: violation data is included in the type_checked event via incrViolate\n }\n\n incrConform(name: string): void {\n this.client.track(\n \"pzod:type_checked\",\n { type_name: name, result: \"conform\" },\n { device_id: this.deviceId },\n );\n }\n\n incrViolate(name: string): void {\n this.client.track(\n \"pzod:type_checked\",\n { type_name: name, result: \"violate\" },\n { device_id: this.deviceId },\n );\n }\n\n // --- Read methods: no-ops (use Amplitude dashboard) ---\n\n async getNames(): Promise<string[]> {\n return [];\n }\n\n async getSamples(_name: string): Promise<string[]> {\n return [];\n }\n\n async getViolations(_name: string, _limit: number): Promise<string[]> {\n return [];\n }\n\n async getStats(_name: string): Promise<{ conform: number; violate: number }> {\n return { conform: 0, violate: 0 };\n }\n\n disconnect(): void {\n // Amplitude SDK manages its own lifecycle — nothing to clean up\n }\n}\n","import type { StorageBackend, ProgressiveConfig } from \"../types.js\";\n\n/**\n * Redis storage backend for production use.\n * Requires `ioredis` as a peer dependency.\n */\nexport class RedisStorage implements StorageBackend {\n private redis: any;\n private prefix: string;\n private maxSamples: number;\n private maxViolations: number;\n\n constructor(config: ProgressiveConfig = {}) {\n this.prefix = config.keyPrefix ?? \"pzod:\";\n this.maxSamples = config.maxSamples ?? 1000;\n this.maxViolations = config.maxViolations ?? 1000;\n }\n\n private async getClient(): Promise<any> {\n if (!this.redis) {\n let Redis: any;\n try {\n // Use a variable to prevent consuming bundlers (e.g. Vite) from\n // statically resolving this optional peer dependency.\n const moduleName = \"ioredis\";\n Redis = (await import(moduleName)).default;\n } catch {\n throw new Error(\n \"ioredis is required for Redis storage. Install it with: npm install ioredis\",\n );\n }\n const url =\n process.env.PROGRESSIVE_ZOD_REDIS_URL ?? \"redis://localhost:6379\";\n this.redis = new Redis(url);\n }\n return this.redis;\n }\n\n async addName(name: string): Promise<void> {\n const r = await this.getClient();\n await r.sadd(`${this.prefix}names`, name).catch(() => {});\n }\n\n async addSample(name: string, sample: string): Promise<void> {\n const r = await this.getClient();\n const p = r.pipeline();\n p.lpush(`${this.prefix}${name}:samples`, sample);\n p.ltrim(`${this.prefix}${name}:samples`, 0, this.maxSamples - 1);\n await p.exec().catch(() => {});\n }\n\n async addViolation(name: string, violation: string): Promise<void> {\n const r = await this.getClient();\n const p = r.pipeline();\n p.lpush(`${this.prefix}${name}:violations`, violation);\n p.ltrim(`${this.prefix}${name}:violations`, 0, this.maxViolations - 1);\n await p.exec().catch(() => {});\n }\n\n async incrConform(name: string): Promise<void> {\n const r = await this.getClient();\n await r.incr(`${this.prefix}${name}:conform`).catch(() => {});\n }\n\n async incrViolate(name: string): Promise<void> {\n const r = await this.getClient();\n await r.incr(`${this.prefix}${name}:violate`).catch(() => {});\n }\n\n async getNames(): Promise<string[]> {\n const r = await this.getClient();\n const names = await r.smembers(`${this.prefix}names`);\n return names.sort();\n }\n\n async getSamples(name: string): Promise<string[]> {\n const r = await this.getClient();\n return r.lrange(`${this.prefix}${name}:samples`, 0, -1);\n }\n\n async getViolations(name: string, limit: number): Promise<string[]> {\n const r = await this.getClient();\n return r.lrange(`${this.prefix}${name}:violations`, 0, limit - 1);\n }\n\n async getStats(\n name: string,\n ): Promise<{ conform: number; violate: number }> {\n const r = await this.getClient();\n const [conform, violate] = await Promise.all([\n r.get(`${this.prefix}${name}:conform`),\n r.get(`${this.prefix}${name}:violate`),\n ]);\n return {\n conform: parseInt(conform ?? \"0\", 10),\n violate: parseInt(violate ?? \"0\", 10),\n };\n }\n\n async disconnect(): Promise<void> {\n if (this.redis) {\n await this.redis.quit();\n this.redis = null;\n }\n }\n}\n","export { progressive, configureBatch, forceFlush, shutdown } from \"./progressive.js\";\nexport { configure } from \"./storage/index.js\";\nexport { inferSchema } from \"./infer-schema.js\";\nexport { schemaToCode } from \"./schema-to-code.js\";\nexport type { ProgressiveConfig, ProgressiveSchema, StorageBackend } from \"./types.js\";\nexport type { BatchConfig } from \"./batch-processor.js\";\nexport type { AmplitudeClient } from \"./storage/amplitude.js\";\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { StorageBackend, ProgressiveConfig } from \"../types.js\";\n\ninterface TypeData {\n samples: string[];\n violations: string[];\n conform: number;\n violate: number;\n}\n\n/**\n * In-memory storage backend with optional file persistence.\n * Perfect for localhost development — no Redis required.\n */\nexport class MemoryStorage implements StorageBackend {\n private names = new Set<string>();\n private data = new Map<string, TypeData>();\n private maxSamples: number;\n private maxViolations: number;\n private dataDir: string | undefined;\n private flushTimer: ReturnType<typeof setTimeout> | undefined;\n\n constructor(config: ProgressiveConfig = {}) {\n this.maxSamples = config.maxSamples ?? 1000;\n this.maxViolations = config.maxViolations ?? 1000;\n this.dataDir = config.dataDir;\n if (this.dataDir) {\n this.loadFromDisk();\n }\n }\n\n private getOrCreate(name: string): TypeData {\n let entry = this.data.get(name);\n if (!entry) {\n entry = { samples: [], violations: [], conform: 0, violate: 0 };\n this.data.set(name, entry);\n }\n return entry;\n }\n\n addName(name: string): void {\n this.names.add(name);\n this.schedulePersist();\n }\n\n addSample(name: string, sample: string): void {\n const entry = this.getOrCreate(name);\n entry.samples.unshift(sample);\n if (entry.samples.length > this.maxSamples) {\n entry.samples.length = this.maxSamples;\n }\n this.schedulePersist();\n }\n\n addViolation(name: string, violation: string): void {\n const entry = this.getOrCreate(name);\n entry.violations.unshift(violation);\n if (entry.violations.length > this.maxViolations) {\n entry.violations.length = this.maxViolations;\n }\n this.schedulePersist();\n }\n\n incrConform(name: string): void {\n this.getOrCreate(name).conform++;\n this.schedulePersist();\n }\n\n incrViolate(name: string): void {\n this.getOrCreate(name).violate++;\n this.schedulePersist();\n }\n\n getNames(): string[] {\n return [...this.names].sort();\n }\n\n getSamples(name: string): string[] {\n return this.getOrCreate(name).samples;\n }\n\n getViolations(name: string, limit: number): string[] {\n return this.getOrCreate(name).violations.slice(0, limit);\n }\n\n async getStats(name: string): Promise<{ conform: number; violate: number }> {\n const entry = this.getOrCreate(name);\n return { conform: entry.conform, violate: entry.violate };\n }\n\n disconnect(): void {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = undefined;\n }\n if (this.dataDir) {\n this.persistToDisk();\n }\n }\n\n private schedulePersist(): void {\n if (!this.dataDir || this.flushTimer) return;\n this.flushTimer = setTimeout(() => {\n this.flushTimer = undefined;\n this.persistToDisk();\n }, 500);\n }\n\n private persistToDisk(): void {\n if (!this.dataDir) return;\n try {\n fs.mkdirSync(this.dataDir, { recursive: true });\n const snapshot = {\n names: [...this.names],\n types: Object.fromEntries(this.data),\n };\n fs.writeFileSync(\n path.join(this.dataDir, \"data.json\"),\n JSON.stringify(snapshot, null, 2),\n );\n } catch {\n // fire-and-forget — never crash the app\n }\n }\n\n private loadFromDisk(): void {\n if (!this.dataDir) return;\n try {\n const raw = fs.readFileSync(\n path.join(this.dataDir, \"data.json\"),\n \"utf-8\",\n );\n const snapshot = JSON.parse(raw);\n if (Array.isArray(snapshot.names)) {\n for (const n of snapshot.names) this.names.add(n);\n }\n if (snapshot.types && typeof snapshot.types === \"object\") {\n for (const [key, val] of Object.entries(snapshot.types)) {\n this.data.set(key, val as TypeData);\n }\n }\n } catch {\n // no data yet — that's fine\n }\n }\n}\n","import type { ProgressiveConfig, StorageBackend } from \"../types.js\";\nimport { MemoryStorage } from \"./memory.js\";\n\nlet currentConfig: ProgressiveConfig = {};\nlet currentStorage: StorageBackend | null = null;\n\nexport type StorageFactory = (\n resolvedConfig: ProgressiveConfig,\n userConfig: ProgressiveConfig,\n) => Promise<StorageBackend>;\n\n// Default factory: memory-only (safe for any environment)\nlet storageFactory: StorageFactory = async (config) => new MemoryStorage(config);\n\n/**\n * Register a storage factory. Called by entry-point modules\n * (storage/index.ts for server, storage/client.ts for client)\n * to control which backends are available.\n */\nexport function _setStorageFactory(factory: StorageFactory): void {\n storageFactory = factory;\n}\n\nexport function configure(config: ProgressiveConfig): void {\n currentConfig = { ...currentConfig, ...config };\n // Force re-creation on next access\n if (currentStorage) {\n currentStorage.disconnect();\n currentStorage = null;\n }\n}\n\nexport function getConfig(): ProgressiveConfig {\n return {\n storage: currentConfig.storage ?? (process.env.PROGRESSIVE_ZOD_STORAGE as any) ?? \"memory\",\n redisUrl: currentConfig.redisUrl ?? process.env.PROGRESSIVE_ZOD_REDIS_URL,\n keyPrefix: currentConfig.keyPrefix ?? process.env.PROGRESSIVE_ZOD_KEY_PREFIX ?? \"pzod:\",\n maxViolations: currentConfig.maxViolations ?? parseInt(process.env.PROGRESSIVE_ZOD_MAX_VIOLATIONS ?? \"1000\", 10),\n maxSamples: currentConfig.maxSamples ?? parseInt(process.env.PROGRESSIVE_ZOD_MAX_SAMPLES ?? \"1000\", 10),\n dataDir: currentConfig.dataDir ?? process.env.PROGRESSIVE_ZOD_DATA_DIR ?? \".progressive-zod\",\n };\n}\n\nexport async function getStorage(): Promise<StorageBackend> {\n if (currentStorage) return currentStorage;\n\n const config = getConfig();\n currentStorage = await storageFactory(config, currentConfig);\n return currentStorage;\n}\n\nexport async function disconnectStorage(): Promise<void> {\n if (currentStorage) {\n await currentStorage.disconnect();\n currentStorage = null;\n }\n}\n","import type { z } from \"zod\";\nimport type { StorageBackend } from \"./types.js\";\nimport { getStorage } from \"./storage/resolve.js\";\n\nexport interface BatchConfig {\n /** Max observations to buffer before forcing a flush. Default: 512 */\n maxQueueSize?: number;\n /** Flush interval in milliseconds. Default: 5000 */\n flushIntervalMs?: number;\n /** Max observations to export per flush. Default: 512 */\n maxExportBatchSize?: number;\n}\n\ninterface Observation {\n name: string;\n serialized: string;\n schema?: z.ZodTypeAny;\n}\n\nconst DEFAULT_MAX_QUEUE_SIZE = 2048;\nconst DEFAULT_FLUSH_INTERVAL_MS = 5000;\nconst DEFAULT_MAX_EXPORT_BATCH_SIZE = 512;\n\nexport class BatchProcessor {\n private queue: Observation[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n private flushing = false;\n private droppedCount = 0;\n\n private readonly maxQueueSize: number;\n private readonly flushIntervalMs: number;\n private readonly maxExportBatchSize: number;\n\n constructor(config: BatchConfig = {}) {\n this.maxQueueSize = config.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE;\n this.flushIntervalMs = config.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;\n this.maxExportBatchSize = config.maxExportBatchSize ?? DEFAULT_MAX_EXPORT_BATCH_SIZE;\n }\n\n /**\n * Enqueue an observation. This is synchronous and fast — no I/O happens here.\n * If the queue is full, the oldest observation is dropped (bounded memory).\n */\n enqueue(name: string, input: unknown, schema?: z.ZodTypeAny): void {\n this.ensureTimer();\n\n let serialized: string;\n try {\n serialized = JSON.stringify(input);\n } catch {\n // Non-serializable input — skip silently\n return;\n }\n\n if (this.queue.length >= this.maxQueueSize) {\n // Drop oldest to stay within bounds\n this.queue.shift();\n this.droppedCount++;\n }\n\n this.queue.push({ name, serialized, schema });\n\n // Flush immediately if we've hit the export batch size\n if (this.queue.length >= this.maxExportBatchSize) {\n this.flushAsync();\n }\n }\n\n /**\n * Force flush all pending observations. Call during graceful shutdown.\n */\n async forceFlush(): Promise<void> {\n this.clearTimer();\n await this.flush();\n }\n\n /**\n * Shut down the processor: flush remaining data and stop the timer.\n */\n async shutdown(): Promise<void> {\n await this.forceFlush();\n }\n\n /** Number of observations currently in the queue */\n get pendingCount(): number {\n return this.queue.length;\n }\n\n /** Number of observations dropped due to queue overflow */\n get dropped(): number {\n return this.droppedCount;\n }\n\n private ensureTimer(): void {\n if (this.timer) return;\n this.timer = setInterval(() => {\n this.flushAsync();\n }, this.flushIntervalMs);\n // Don't keep the process alive just for telemetry\n if (this.timer && typeof this.timer === \"object\" && \"unref\" in this.timer) {\n this.timer.unref();\n }\n }\n\n private clearTimer(): void {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n\n /** Non-blocking flush — errors are swallowed */\n private flushAsync(): void {\n this.flush().catch(() => {});\n }\n\n /** Drain the queue and send observations to storage in batch */\n private async flush(): Promise<void> {\n if (this.flushing || this.queue.length === 0) return;\n this.flushing = true;\n\n // Drain up to maxExportBatchSize\n const batch = this.queue.splice(0, this.maxExportBatchSize);\n\n try {\n const storage = await getStorage();\n await this.exportBatch(storage, batch);\n } catch {\n // Swallow errors — observability must never crash the app\n } finally {\n this.flushing = false;\n // If items accumulated during flush, schedule another\n if (this.queue.length >= this.maxExportBatchSize) {\n this.flushAsync();\n }\n }\n }\n\n private async exportBatch(\n storage: StorageBackend,\n batch: Observation[],\n ): Promise<void> {\n // Collect unique names first\n const names = new Set<string>();\n for (const obs of batch) {\n names.add(obs.name);\n }\n\n // Register all names\n await Promise.all([...names].map((n) => storage.addName(n)));\n\n // Process each observation\n // We batch the promises to avoid creating thousands of concurrent promises\n const promises: Promise<void>[] = [];\n\n for (const obs of batch) {\n promises.push(this.exportOne(storage, obs));\n }\n\n await Promise.all(promises);\n }\n\n private async exportOne(\n storage: StorageBackend,\n obs: Observation,\n ): Promise<void> {\n await storage.addSample(obs.name, obs.serialized);\n\n if (obs.schema) {\n const result = obs.schema.safeParse(JSON.parse(obs.serialized));\n if (result.success) {\n await storage.incrConform(obs.name);\n } else {\n await storage.incrViolate(obs.name);\n await storage.addViolation(obs.name, obs.serialized);\n }\n } else {\n await storage.incrViolate(obs.name);\n await storage.addViolation(obs.name, obs.serialized);\n }\n }\n}\n","import type { z } from \"zod\";\nimport type { ProgressiveSchema } from \"./types.js\";\nimport { BatchProcessor } from \"./batch-processor.js\";\nimport type { BatchConfig } from \"./batch-processor.js\";\n\nlet processor: BatchProcessor | null = null;\n\nfunction getProcessor(): BatchProcessor {\n if (!processor) {\n processor = new BatchProcessor();\n }\n return processor;\n}\n\n/**\n * Configure the batch processor. Call before first `progressive()` use.\n * Follows the OpenTelemetry provider pattern:\n * - Observations are buffered in memory (synchronous, zero I/O on hot path)\n * - Flushed to storage in batches on a timer or when buffer is full\n * - Queue is bounded to prevent memory leaks\n * - Timer is unref'd so it won't keep the process alive\n */\nexport function configureBatch(config: BatchConfig): void {\n if (processor) {\n // Flush existing before reconfiguring\n processor.forceFlush().catch(() => {});\n }\n processor = new BatchProcessor(config);\n}\n\n/**\n * Force flush all pending observations. Call during graceful shutdown.\n *\n * @example\n * ```ts\n * process.on(\"SIGTERM\", async () => {\n * await forceFlush();\n * process.exit(0);\n * });\n * ```\n */\nexport async function forceFlush(): Promise<void> {\n if (processor) {\n await processor.forceFlush();\n }\n}\n\n/**\n * Shut down the batch processor and flush remaining data.\n */\nexport async function shutdown(): Promise<void> {\n if (processor) {\n await processor.shutdown();\n processor = null;\n }\n}\n\n/**\n * Create a progressive schema that tracks runtime data and optionally validates.\n *\n * - Never throws — always returns input unchanged\n * - Records samples for later schema inference\n * - If a schema is provided, tracks conformance vs violations\n * - Observations are batched and flushed asynchronously (OTel-style)\n * - Zero I/O on the hot path — enqueue is synchronous\n */\nexport function progressive(\n name: string,\n schema?: z.ZodTypeAny,\n): ProgressiveSchema {\n return {\n parse(input: unknown): unknown {\n // Synchronous enqueue — no I/O, no promises, no overhead\n getProcessor().enqueue(name, input, schema);\n return input;\n },\n };\n}\n","import { _setStorageFactory } from \"./resolve.js\";\nimport { MemoryStorage } from \"./memory.js\";\n\n// Register server storage factory — supports all backends including Redis\n_setStorageFactory(async (config, userConfig) => {\n if (config.storage === \"amplitude\") {\n if (!userConfig.amplitudeClient) {\n throw new Error(\n \"progressive-zod: storage is set to 'amplitude' but no amplitudeClient was provided. \" +\n \"Pass an Amplitude client instance via configure({ amplitudeClient }).\",\n );\n }\n const { AmplitudeStorage } = await import(\"./amplitude.js\");\n return new AmplitudeStorage(userConfig.amplitudeClient, config);\n } else if (config.storage === \"redis\") {\n // Dynamic import so ioredis isn't loaded unless needed\n const { RedisStorage } = await import(\"./redis.js\");\n return new RedisStorage(config);\n }\n\n return new MemoryStorage(config);\n});\n\nexport { configure, getConfig, getStorage, disconnectStorage } from \"./resolve.js\";\n","import { z } from \"zod\";\n\n/**\n * Infer a Zod schema from an array of runtime samples.\n */\nexport function inferSchema(samples: unknown[]): z.ZodTypeAny {\n const objects = samples.filter(\n (s): s is Record<string, unknown> =>\n typeof s === \"object\" && s !== null && !Array.isArray(s),\n );\n\n if (objects.length === 0) {\n return inferPrimitiveUnion(samples);\n }\n\n // Group samples by their shape (set of keys)\n const groups = groupByShape(objects);\n\n if (groups.length === 1) {\n return buildObjectSchema(groups[0]);\n }\n\n // Try to find a discriminator field\n const discriminator = findDiscriminator(groups);\n if (discriminator) {\n return z.discriminatedUnion(\n discriminator,\n groups.map(\n (group) => buildObjectSchema(group) as z.ZodObject<any>,\n ) as any,\n );\n }\n\n return z.union(\n groups.map((group) => buildObjectSchema(group)) as any,\n );\n}\n\nfunction shapeKey(obj: Record<string, unknown>): string {\n return Object.keys(obj).sort().join(\",\");\n}\n\nfunction groupByShape(\n objects: Record<string, unknown>[],\n): Record<string, unknown>[][] {\n const map = new Map<string, Record<string, unknown>[]>();\n for (const obj of objects) {\n const key = shapeKey(obj);\n let group = map.get(key);\n if (!group) {\n group = [];\n map.set(key, group);\n }\n group.push(obj);\n }\n return [...map.values()];\n}\n\nfunction findDiscriminator(\n groups: Record<string, unknown>[][],\n): string | null {\n if (groups.length < 2) return null;\n\n // Get keys present in all groups\n const keySets = groups.map(\n (g) => new Set(Object.keys(g[0])),\n );\n const commonKeys = [...keySets[0]].filter((k) =>\n keySets.every((s) => s.has(k)),\n );\n\n for (const key of commonKeys) {\n // Check if this key has a single string literal value per group\n // and the values are distinct across groups\n const values = new Set<string>();\n let valid = true;\n\n for (const group of groups) {\n const groupValues = new Set(\n group.map((obj) => obj[key]).filter((v) => typeof v === \"string\"),\n );\n if (groupValues.size !== 1) {\n valid = false;\n break;\n }\n const val = [...groupValues][0] as string;\n if (values.has(val)) {\n valid = false;\n break;\n }\n values.add(val);\n }\n\n if (valid && values.size === groups.length) {\n return key;\n }\n }\n\n return null;\n}\n\nfunction buildObjectSchema(\n samples: Record<string, unknown>[],\n): z.ZodObject<any> {\n const keys = Object.keys(samples[0]);\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const key of keys) {\n const values = samples.map((s) => s[key]);\n // If all values are the same string, use z.literal() (needed for discriminated unions)\n const unique = new Set(values);\n if (unique.size === 1 && typeof values[0] === \"string\") {\n shape[key] = z.literal(values[0] as string);\n } else {\n shape[key] = inferFieldType(values);\n }\n }\n\n return z.object(shape).strict();\n}\n\nfunction inferFieldType(values: unknown[]): z.ZodTypeAny {\n const types = new Set(values.map(classifyValue));\n\n if (types.size === 1) {\n const type = [...types][0];\n if (type === \"string\") return z.string();\n if (type === \"number\") return z.number();\n if (type === \"boolean\") return z.boolean();\n if (type === \"null\") return z.null();\n if (type === \"object\") {\n return inferSchema(values);\n }\n if (type === \"array\") {\n const allItems = values.flatMap((v) =>\n Array.isArray(v) ? v : [],\n );\n if (allItems.length === 0) return z.array(z.unknown());\n return z.array(inferFieldType(allItems));\n }\n }\n\n // Check if it's string literal values (for discriminator fields)\n if (types.size === 1 && types.has(\"string\")) {\n const unique = new Set(values);\n if (unique.size === 1) {\n return z.literal(values[0] as string);\n }\n }\n\n // Mixed types — build a union\n const members: z.ZodTypeAny[] = [];\n if (types.has(\"string\")) members.push(z.string());\n if (types.has(\"number\")) members.push(z.number());\n if (types.has(\"boolean\")) members.push(z.boolean());\n if (types.has(\"null\")) members.push(z.null());\n if (types.has(\"object\")) {\n const objs = values.filter(\n (v) => typeof v === \"object\" && v !== null && !Array.isArray(v),\n );\n members.push(inferSchema(objs));\n }\n if (types.has(\"array\")) {\n const arrs = values.filter(Array.isArray);\n const allItems = arrs.flat();\n members.push(\n z.array(allItems.length > 0 ? inferFieldType(allItems) : z.unknown()),\n );\n }\n\n if (members.length === 1) return members[0];\n if (members.length === 2) return z.union([members[0], members[1]] as any);\n return z.union(members as any);\n}\n\nfunction classifyValue(v: unknown): string {\n if (v === null) return \"null\";\n if (Array.isArray(v)) return \"array\";\n return typeof v;\n}\n\nfunction inferPrimitiveUnion(samples: unknown[]): z.ZodTypeAny {\n const types = new Set(samples.map(classifyValue));\n const members: z.ZodTypeAny[] = [];\n if (types.has(\"string\")) members.push(z.string());\n if (types.has(\"number\")) members.push(z.number());\n if (types.has(\"boolean\")) members.push(z.boolean());\n if (types.has(\"null\")) members.push(z.null());\n if (members.length === 0) return z.unknown();\n if (members.length === 1) return members[0];\n return z.union(members as any);\n}\n","import { z } from \"zod\";\n\n/**\n * Convert a Zod schema into readable TypeScript code that recreates it.\n */\nexport function schemaToCode(schema: z.ZodTypeAny, indent = 0): string {\n const pad = \" \".repeat(indent);\n\n if (schema instanceof z.ZodString) return \"z.string()\";\n if (schema instanceof z.ZodNumber) return \"z.number()\";\n if (schema instanceof z.ZodBoolean) return \"z.boolean()\";\n if (schema instanceof z.ZodNull) return \"z.null()\";\n if (schema instanceof z.ZodUnknown) return \"z.unknown()\";\n\n if (schema instanceof z.ZodLiteral) {\n const val = schema.value;\n return typeof val === \"string\" ? `z.literal(\"${val}\")` : `z.literal(${val})`;\n }\n\n if (schema instanceof z.ZodArray) {\n const inner = schemaToCode(schema.element, indent);\n return `z.array(${inner})`;\n }\n\n if (schema instanceof z.ZodObject) {\n const shape = schema.shape as Record<string, z.ZodTypeAny>;\n const keys = Object.keys(shape);\n if (keys.length === 0) return \"z.object({})\";\n\n const inner = pad + \" \";\n const fields = keys.map(\n (k) => `${inner}${safeProp(k)}: ${schemaToCode(shape[k], indent + 1)},`,\n );\n\n const strict =\n schema._def && (schema._def as any).unknownKeys === \"strict\"\n ? \".strict()\"\n : \"\";\n\n return `z.object({\\n${fields.join(\"\\n\")}\\n${pad}})${strict}`;\n }\n\n if (schema instanceof z.ZodUnion) {\n const opts = (schema as any).options as z.ZodTypeAny[];\n const members = opts.map((o) => schemaToCode(o, indent));\n if (members.every((m) => !m.includes(\"\\n\"))) {\n return `z.union([${members.join(\", \")}])`;\n }\n const inner = pad + \" \";\n return `z.union([\\n${members.map((m) => `${inner}${m},`).join(\"\\n\")}\\n${pad}])`;\n }\n\n if (schema instanceof z.ZodDiscriminatedUnion) {\n const disc = (schema as any)._def.discriminator as string;\n const opts = (schema as any)._def.options as z.ZodTypeAny[];\n const members = opts.map((o) => schemaToCode(o, indent + 1));\n const inner = pad + \" \";\n return `z.discriminatedUnion(\"${disc}\", [\\n${members.map((m) => `${inner}${m},`).join(\"\\n\")}\\n${pad}])`;\n }\n\n return \"z.unknown()\";\n}\n\nfunction safeProp(key: string): string {\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : `\"${key}\"`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA,IA+Ba;AA/Bb;AAAA;AAAA;AA+BO,IAAM,mBAAN,MAAiD;AAAA,MACrC;AAAA,MACA;AAAA,MAEjB,YACE,QACA,QACA;AACA,aAAK,SAAS;AAEd,aAAK,WAAW,QAAQ,OAAO,aAAa,SAAS;AAAA,MACvD;AAAA,MAEA,QAAQ,OAAqB;AAAA,MAE7B;AAAA,MAEA,UAAU,OAAe,SAAuB;AAAA,MAEhD;AAAA,MAEA,aAAa,OAAe,YAA0B;AAAA,MAEtD;AAAA,MAEA,YAAY,MAAoB;AAC9B,aAAK,OAAO;AAAA,UACV;AAAA,UACA,EAAE,WAAW,MAAM,QAAQ,UAAU;AAAA,UACrC,EAAE,WAAW,KAAK,SAAS;AAAA,QAC7B;AAAA,MACF;AAAA,MAEA,YAAY,MAAoB;AAC9B,aAAK,OAAO;AAAA,UACV;AAAA,UACA,EAAE,WAAW,MAAM,QAAQ,UAAU;AAAA,UACrC,EAAE,WAAW,KAAK,SAAS;AAAA,QAC7B;AAAA,MACF;AAAA;AAAA,MAIA,MAAM,WAA8B;AAClC,eAAO,CAAC;AAAA,MACV;AAAA,MAEA,MAAM,WAAW,OAAkC;AACjD,eAAO,CAAC;AAAA,MACV;AAAA,MAEA,MAAM,cAAc,OAAe,QAAmC;AACpE,eAAO,CAAC;AAAA,MACV;AAAA,MAEA,MAAM,SAAS,OAA8D;AAC3E,eAAO,EAAE,SAAS,GAAG,SAAS,EAAE;AAAA,MAClC;AAAA,MAEA,aAAmB;AAAA,MAEnB;AAAA,IACF;AAAA;AAAA;;;AC7FA;AAAA;AAAA;AAAA;AAAA,IAMa;AANb;AAAA;AAAA;AAMO,IAAM,eAAN,MAA6C;AAAA,MAC1C;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAER,YAAY,SAA4B,CAAC,GAAG;AAC1C,aAAK,SAAS,OAAO,aAAa;AAClC,aAAK,aAAa,OAAO,cAAc;AACvC,aAAK,gBAAgB,OAAO,iBAAiB;AAAA,MAC/C;AAAA,MAEA,MAAc,YAA0B;AACtC,YAAI,CAAC,KAAK,OAAO;AACf,cAAI;AACJ,cAAI;AAGF,kBAAM,aAAa;AACnB,qBAAS,MAAM,OAAO,aAAa;AAAA,UACrC,QAAQ;AACN,kBAAM,IAAI;AAAA,cACR;AAAA,YACF;AAAA,UACF;AACA,gBAAM,MACJ,QAAQ,IAAI,6BAA6B;AAC3C,eAAK,QAAQ,IAAI,MAAM,GAAG;AAAA,QAC5B;AACA,eAAO,KAAK;AAAA,MACd;AAAA,MAEA,MAAM,QAAQ,MAA6B;AACzC,cAAM,IAAI,MAAM,KAAK,UAAU;AAC/B,cAAM,EAAE,KAAK,GAAG,KAAK,MAAM,SAAS,IAAI,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MAC1D;AAAA,MAEA,MAAM,UAAU,MAAc,QAA+B;AAC3D,cAAM,IAAI,MAAM,KAAK,UAAU;AAC/B,cAAM,IAAI,EAAE,SAAS;AACrB,UAAE,MAAM,GAAG,KAAK,MAAM,GAAG,IAAI,YAAY,MAAM;AAC/C,UAAE,MAAM,GAAG,KAAK,MAAM,GAAG,IAAI,YAAY,GAAG,KAAK,aAAa,CAAC;AAC/D,cAAM,EAAE,KAAK,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MAC/B;AAAA,MAEA,MAAM,aAAa,MAAc,WAAkC;AACjE,cAAM,IAAI,MAAM,KAAK,UAAU;AAC/B,cAAM,IAAI,EAAE,SAAS;AACrB,UAAE,MAAM,GAAG,KAAK,MAAM,GAAG,IAAI,eAAe,SAAS;AACrD,UAAE,MAAM,GAAG,KAAK,MAAM,GAAG,IAAI,eAAe,GAAG,KAAK,gBAAgB,CAAC;AACrE,cAAM,EAAE,KAAK,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MAC/B;AAAA,MAEA,MAAM,YAAY,MAA6B;AAC7C,cAAM,IAAI,MAAM,KAAK,UAAU;AAC/B,cAAM,EAAE,KAAK,GAAG,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MAC9D;AAAA,MAEA,MAAM,YAAY,MAA6B;AAC7C,cAAM,IAAI,MAAM,KAAK,UAAU;AAC/B,cAAM,EAAE,KAAK,GAAG,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MAC9D;AAAA,MAEA,MAAM,WAA8B;AAClC,cAAM,IAAI,MAAM,KAAK,UAAU;AAC/B,cAAM,QAAQ,MAAM,EAAE,SAAS,GAAG,KAAK,MAAM,OAAO;AACpD,eAAO,MAAM,KAAK;AAAA,MACpB;AAAA,MAEA,MAAM,WAAW,MAAiC;AAChD,cAAM,IAAI,MAAM,KAAK,UAAU;AAC/B,eAAO,EAAE,OAAO,GAAG,KAAK,MAAM,GAAG,IAAI,YAAY,GAAG,EAAE;AAAA,MACxD;AAAA,MAEA,MAAM,cAAc,MAAc,OAAkC;AAClE,cAAM,IAAI,MAAM,KAAK,UAAU;AAC/B,eAAO,EAAE,OAAO,GAAG,KAAK,MAAM,GAAG,IAAI,eAAe,GAAG,QAAQ,CAAC;AAAA,MAClE;AAAA,MAEA,MAAM,SACJ,MAC+C;AAC/C,cAAM,IAAI,MAAM,KAAK,UAAU;AAC/B,cAAM,CAAC,SAAS,OAAO,IAAI,MAAM,QAAQ,IAAI;AAAA,UAC3C,EAAE,IAAI,GAAG,KAAK,MAAM,GAAG,IAAI,UAAU;AAAA,UACrC,EAAE,IAAI,GAAG,KAAK,MAAM,GAAG,IAAI,UAAU;AAAA,QACvC,CAAC;AACD,eAAO;AAAA,UACL,SAAS,SAAS,WAAW,KAAK,EAAE;AAAA,UACpC,SAAS,SAAS,WAAW,KAAK,EAAE;AAAA,QACtC;AAAA,MACF;AAAA,MAEA,MAAM,aAA4B;AAChC,YAAI,KAAK,OAAO;AACd,gBAAM,KAAK,MAAM,KAAK;AACtB,eAAK,QAAQ;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACzGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,SAAoB;AACpB,WAAsB;AAcf,IAAM,gBAAN,MAA8C;AAAA,EAC3C,QAAQ,oBAAI,IAAY;AAAA,EACxB,OAAO,oBAAI,IAAsB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,SAA4B,CAAC,GAAG;AAC1C,SAAK,aAAa,OAAO,cAAc;AACvC,SAAK,gBAAgB,OAAO,iBAAiB;AAC7C,SAAK,UAAU,OAAO;AACtB,QAAI,KAAK,SAAS;AAChB,WAAK,aAAa;AAAA,IACpB;AAAA,EACF;AAAA,EAEQ,YAAY,MAAwB;AAC1C,QAAI,QAAQ,KAAK,KAAK,IAAI,IAAI;AAC9B,QAAI,CAAC,OAAO;AACV,cAAQ,EAAE,SAAS,CAAC,GAAG,YAAY,CAAC,GAAG,SAAS,GAAG,SAAS,EAAE;AAC9D,WAAK,KAAK,IAAI,MAAM,KAAK;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,MAAoB;AAC1B,SAAK,MAAM,IAAI,IAAI;AACnB,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,UAAU,MAAc,QAAsB;AAC5C,UAAM,QAAQ,KAAK,YAAY,IAAI;AACnC,UAAM,QAAQ,QAAQ,MAAM;AAC5B,QAAI,MAAM,QAAQ,SAAS,KAAK,YAAY;AAC1C,YAAM,QAAQ,SAAS,KAAK;AAAA,IAC9B;AACA,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,aAAa,MAAc,WAAyB;AAClD,UAAM,QAAQ,KAAK,YAAY,IAAI;AACnC,UAAM,WAAW,QAAQ,SAAS;AAClC,QAAI,MAAM,WAAW,SAAS,KAAK,eAAe;AAChD,YAAM,WAAW,SAAS,KAAK;AAAA,IACjC;AACA,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,YAAY,MAAoB;AAC9B,SAAK,YAAY,IAAI,EAAE;AACvB,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,YAAY,MAAoB;AAC9B,SAAK,YAAY,IAAI,EAAE;AACvB,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,WAAqB;AACnB,WAAO,CAAC,GAAG,KAAK,KAAK,EAAE,KAAK;AAAA,EAC9B;AAAA,EAEA,WAAW,MAAwB;AACjC,WAAO,KAAK,YAAY,IAAI,EAAE;AAAA,EAChC;AAAA,EAEA,cAAc,MAAc,OAAyB;AACnD,WAAO,KAAK,YAAY,IAAI,EAAE,WAAW,MAAM,GAAG,KAAK;AAAA,EACzD;AAAA,EAEA,MAAM,SAAS,MAA6D;AAC1E,UAAM,QAAQ,KAAK,YAAY,IAAI;AACnC,WAAO,EAAE,SAAS,MAAM,SAAS,SAAS,MAAM,QAAQ;AAAA,EAC1D;AAAA,EAEA,aAAmB;AACjB,QAAI,KAAK,YAAY;AACnB,mBAAa,KAAK,UAAU;AAC5B,WAAK,aAAa;AAAA,IACpB;AACA,QAAI,KAAK,SAAS;AAChB,WAAK,cAAc;AAAA,IACrB;AAAA,EACF;AAAA,EAEQ,kBAAwB;AAC9B,QAAI,CAAC,KAAK,WAAW,KAAK,WAAY;AACtC,SAAK,aAAa,WAAW,MAAM;AACjC,WAAK,aAAa;AAClB,WAAK,cAAc;AAAA,IACrB,GAAG,GAAG;AAAA,EACR;AAAA,EAEQ,gBAAsB;AAC5B,QAAI,CAAC,KAAK,QAAS;AACnB,QAAI;AACF,MAAG,aAAU,KAAK,SAAS,EAAE,WAAW,KAAK,CAAC;AAC9C,YAAM,WAAW;AAAA,QACf,OAAO,CAAC,GAAG,KAAK,KAAK;AAAA,QACrB,OAAO,OAAO,YAAY,KAAK,IAAI;AAAA,MACrC;AACA,MAAG;AAAA,QACI,UAAK,KAAK,SAAS,WAAW;AAAA,QACnC,KAAK,UAAU,UAAU,MAAM,CAAC;AAAA,MAClC;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEQ,eAAqB;AAC3B,QAAI,CAAC,KAAK,QAAS;AACnB,QAAI;AACF,YAAM,MAAS;AAAA,QACR,UAAK,KAAK,SAAS,WAAW;AAAA,QACnC;AAAA,MACF;AACA,YAAM,WAAW,KAAK,MAAM,GAAG;AAC/B,UAAI,MAAM,QAAQ,SAAS,KAAK,GAAG;AACjC,mBAAW,KAAK,SAAS,MAAO,MAAK,MAAM,IAAI,CAAC;AAAA,MAClD;AACA,UAAI,SAAS,SAAS,OAAO,SAAS,UAAU,UAAU;AACxD,mBAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,SAAS,KAAK,GAAG;AACvD,eAAK,KAAK,IAAI,KAAK,GAAe;AAAA,QACpC;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACF;;;AC/IA,IAAI,gBAAmC,CAAC;AACxC,IAAI,iBAAwC;AAQ5C,IAAI,iBAAiC,OAAO,WAAW,IAAI,cAAc,MAAM;AAOxE,SAAS,mBAAmB,SAA+B;AAChE,mBAAiB;AACnB;AAEO,SAAS,UAAU,QAAiC;AACzD,kBAAgB,EAAE,GAAG,eAAe,GAAG,OAAO;AAE9C,MAAI,gBAAgB;AAClB,mBAAe,WAAW;AAC1B,qBAAiB;AAAA,EACnB;AACF;AAEO,SAAS,YAA+B;AAC7C,SAAO;AAAA,IACL,SAAS,cAAc,WAAY,QAAQ,IAAI,2BAAmC;AAAA,IAClF,UAAU,cAAc,YAAY,QAAQ,IAAI;AAAA,IAChD,WAAW,cAAc,aAAa,QAAQ,IAAI,8BAA8B;AAAA,IAChF,eAAe,cAAc,iBAAiB,SAAS,QAAQ,IAAI,kCAAkC,QAAQ,EAAE;AAAA,IAC/G,YAAY,cAAc,cAAc,SAAS,QAAQ,IAAI,+BAA+B,QAAQ,EAAE;AAAA,IACtG,SAAS,cAAc,WAAW,QAAQ,IAAI,4BAA4B;AAAA,EAC5E;AACF;AAEA,eAAsB,aAAsC;AAC1D,MAAI,eAAgB,QAAO;AAE3B,QAAM,SAAS,UAAU;AACzB,mBAAiB,MAAM,eAAe,QAAQ,aAAa;AAC3D,SAAO;AACT;;;AC9BA,IAAM,yBAAyB;AAC/B,IAAM,4BAA4B;AAClC,IAAM,gCAAgC;AAE/B,IAAM,iBAAN,MAAqB;AAAA,EAClB,QAAuB,CAAC;AAAA,EACxB,QAA+C;AAAA,EAC/C,WAAW;AAAA,EACX,eAAe;AAAA,EAEN;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,SAAsB,CAAC,GAAG;AACpC,SAAK,eAAe,OAAO,gBAAgB;AAC3C,SAAK,kBAAkB,OAAO,mBAAmB;AACjD,SAAK,qBAAqB,OAAO,sBAAsB;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQ,MAAc,OAAgB,QAA6B;AACjE,SAAK,YAAY;AAEjB,QAAI;AACJ,QAAI;AACF,mBAAa,KAAK,UAAU,KAAK;AAAA,IACnC,QAAQ;AAEN;AAAA,IACF;AAEA,QAAI,KAAK,MAAM,UAAU,KAAK,cAAc;AAE1C,WAAK,MAAM,MAAM;AACjB,WAAK;AAAA,IACP;AAEA,SAAK,MAAM,KAAK,EAAE,MAAM,YAAY,OAAO,CAAC;AAG5C,QAAI,KAAK,MAAM,UAAU,KAAK,oBAAoB;AAChD,WAAK,WAAW;AAAA,IAClB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aAA4B;AAChC,SAAK,WAAW;AAChB,UAAM,KAAK,MAAM;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WAA0B;AAC9B,UAAM,KAAK,WAAW;AAAA,EACxB;AAAA;AAAA,EAGA,IAAI,eAAuB;AACzB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA;AAAA,EAGA,IAAI,UAAkB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,cAAoB;AAC1B,QAAI,KAAK,MAAO;AAChB,SAAK,QAAQ,YAAY,MAAM;AAC7B,WAAK,WAAW;AAAA,IAClB,GAAG,KAAK,eAAe;AAEvB,QAAI,KAAK,SAAS,OAAO,KAAK,UAAU,YAAY,WAAW,KAAK,OAAO;AACzE,WAAK,MAAM,MAAM;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,aAAmB;AACzB,QAAI,KAAK,OAAO;AACd,oBAAc,KAAK,KAAK;AACxB,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AAAA;AAAA,EAGQ,aAAmB;AACzB,SAAK,MAAM,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EAC7B;AAAA;AAAA,EAGA,MAAc,QAAuB;AACnC,QAAI,KAAK,YAAY,KAAK,MAAM,WAAW,EAAG;AAC9C,SAAK,WAAW;AAGhB,UAAM,QAAQ,KAAK,MAAM,OAAO,GAAG,KAAK,kBAAkB;AAE1D,QAAI;AACF,YAAM,UAAU,MAAM,WAAW;AACjC,YAAM,KAAK,YAAY,SAAS,KAAK;AAAA,IACvC,QAAQ;AAAA,IAER,UAAE;AACA,WAAK,WAAW;AAEhB,UAAI,KAAK,MAAM,UAAU,KAAK,oBAAoB;AAChD,aAAK,WAAW;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,YACZ,SACA,OACe;AAEf,UAAM,QAAQ,oBAAI,IAAY;AAC9B,eAAW,OAAO,OAAO;AACvB,YAAM,IAAI,IAAI,IAAI;AAAA,IACpB;AAGA,UAAM,QAAQ,IAAI,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,MAAM,QAAQ,QAAQ,CAAC,CAAC,CAAC;AAI3D,UAAM,WAA4B,CAAC;AAEnC,eAAW,OAAO,OAAO;AACvB,eAAS,KAAK,KAAK,UAAU,SAAS,GAAG,CAAC;AAAA,IAC5C;AAEA,UAAM,QAAQ,IAAI,QAAQ;AAAA,EAC5B;AAAA,EAEA,MAAc,UACZ,SACA,KACe;AACf,UAAM,QAAQ,UAAU,IAAI,MAAM,IAAI,UAAU;AAEhD,QAAI,IAAI,QAAQ;AACd,YAAM,SAAS,IAAI,OAAO,UAAU,KAAK,MAAM,IAAI,UAAU,CAAC;AAC9D,UAAI,OAAO,SAAS;AAClB,cAAM,QAAQ,YAAY,IAAI,IAAI;AAAA,MACpC,OAAO;AACL,cAAM,QAAQ,YAAY,IAAI,IAAI;AAClC,cAAM,QAAQ,aAAa,IAAI,MAAM,IAAI,UAAU;AAAA,MACrD;AAAA,IACF,OAAO;AACL,YAAM,QAAQ,YAAY,IAAI,IAAI;AAClC,YAAM,QAAQ,aAAa,IAAI,MAAM,IAAI,UAAU;AAAA,IACrD;AAAA,EACF;AACF;;;AChLA,IAAI,YAAmC;AAEvC,SAAS,eAA+B;AACtC,MAAI,CAAC,WAAW;AACd,gBAAY,IAAI,eAAe;AAAA,EACjC;AACA,SAAO;AACT;AAUO,SAAS,eAAe,QAA2B;AACxD,MAAI,WAAW;AAEb,cAAU,WAAW,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EACvC;AACA,cAAY,IAAI,eAAe,MAAM;AACvC;AAaA,eAAsB,aAA4B;AAChD,MAAI,WAAW;AACb,UAAM,UAAU,WAAW;AAAA,EAC7B;AACF;AAKA,eAAsB,WAA0B;AAC9C,MAAI,WAAW;AACb,UAAM,UAAU,SAAS;AACzB,gBAAY;AAAA,EACd;AACF;AAWO,SAAS,YACd,MACA,QACmB;AACnB,SAAO;AAAA,IACL,MAAM,OAAyB;AAE7B,mBAAa,EAAE,QAAQ,MAAM,OAAO,MAAM;AAC1C,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;ACzEA,mBAAmB,OAAO,QAAQ,eAAe;AAC/C,MAAI,OAAO,YAAY,aAAa;AAClC,QAAI,CAAC,WAAW,iBAAiB;AAC/B,YAAM,IAAI;AAAA,QACR;AAAA,MAEF;AAAA,IACF;AACA,UAAM,EAAE,kBAAAA,kBAAiB,IAAI,MAAM;AACnC,WAAO,IAAIA,kBAAiB,WAAW,iBAAiB,MAAM;AAAA,EAChE,WAAW,OAAO,YAAY,SAAS;AAErC,UAAM,EAAE,cAAAC,cAAa,IAAI,MAAM;AAC/B,WAAO,IAAIA,cAAa,MAAM;AAAA,EAChC;AAEA,SAAO,IAAI,cAAc,MAAM;AACjC,CAAC;;;ACrBD,iBAAkB;AAKX,SAAS,YAAY,SAAkC;AAC5D,QAAM,UAAU,QAAQ;AAAA,IACtB,CAAC,MACC,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAAA,EAC3D;AAEA,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,oBAAoB,OAAO;AAAA,EACpC;AAGA,QAAM,SAAS,aAAa,OAAO;AAEnC,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO,kBAAkB,OAAO,CAAC,CAAC;AAAA,EACpC;AAGA,QAAM,gBAAgB,kBAAkB,MAAM;AAC9C,MAAI,eAAe;AACjB,WAAO,aAAE;AAAA,MACP;AAAA,MACA,OAAO;AAAA,QACL,CAAC,UAAU,kBAAkB,KAAK;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AAEA,SAAO,aAAE;AAAA,IACP,OAAO,IAAI,CAAC,UAAU,kBAAkB,KAAK,CAAC;AAAA,EAChD;AACF;AAEA,SAAS,SAAS,KAAsC;AACtD,SAAO,OAAO,KAAK,GAAG,EAAE,KAAK,EAAE,KAAK,GAAG;AACzC;AAEA,SAAS,aACP,SAC6B;AAC7B,QAAM,MAAM,oBAAI,IAAuC;AACvD,aAAW,OAAO,SAAS;AACzB,UAAM,MAAM,SAAS,GAAG;AACxB,QAAI,QAAQ,IAAI,IAAI,GAAG;AACvB,QAAI,CAAC,OAAO;AACV,cAAQ,CAAC;AACT,UAAI,IAAI,KAAK,KAAK;AAAA,IACpB;AACA,UAAM,KAAK,GAAG;AAAA,EAChB;AACA,SAAO,CAAC,GAAG,IAAI,OAAO,CAAC;AACzB;AAEA,SAAS,kBACP,QACe;AACf,MAAI,OAAO,SAAS,EAAG,QAAO;AAG9B,QAAM,UAAU,OAAO;AAAA,IACrB,CAAC,MAAM,IAAI,IAAI,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC;AAAA,EAClC;AACA,QAAM,aAAa,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE;AAAA,IAAO,CAAC,MACzC,QAAQ,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAAA,EAC/B;AAEA,aAAW,OAAO,YAAY;AAG5B,UAAM,SAAS,oBAAI,IAAY;AAC/B,QAAI,QAAQ;AAEZ,eAAW,SAAS,QAAQ;AAC1B,YAAM,cAAc,IAAI;AAAA,QACtB,MAAM,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC,EAAE,OAAO,CAAC,MAAM,OAAO,MAAM,QAAQ;AAAA,MAClE;AACA,UAAI,YAAY,SAAS,GAAG;AAC1B,gBAAQ;AACR;AAAA,MACF;AACA,YAAM,MAAM,CAAC,GAAG,WAAW,EAAE,CAAC;AAC9B,UAAI,OAAO,IAAI,GAAG,GAAG;AACnB,gBAAQ;AACR;AAAA,MACF;AACA,aAAO,IAAI,GAAG;AAAA,IAChB;AAEA,QAAI,SAAS,OAAO,SAAS,OAAO,QAAQ;AAC1C,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,kBACP,SACkB;AAClB,QAAM,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC;AACnC,QAAM,QAAsC,CAAC;AAE7C,aAAW,OAAO,MAAM;AACtB,UAAM,SAAS,QAAQ,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;AAExC,UAAM,SAAS,IAAI,IAAI,MAAM;AAC7B,QAAI,OAAO,SAAS,KAAK,OAAO,OAAO,CAAC,MAAM,UAAU;AACtD,YAAM,GAAG,IAAI,aAAE,QAAQ,OAAO,CAAC,CAAW;AAAA,IAC5C,OAAO;AACL,YAAM,GAAG,IAAI,eAAe,MAAM;AAAA,IACpC;AAAA,EACF;AAEA,SAAO,aAAE,OAAO,KAAK,EAAE,OAAO;AAChC;AAEA,SAAS,eAAe,QAAiC;AACvD,QAAM,QAAQ,IAAI,IAAI,OAAO,IAAI,aAAa,CAAC;AAE/C,MAAI,MAAM,SAAS,GAAG;AACpB,UAAM,OAAO,CAAC,GAAG,KAAK,EAAE,CAAC;AACzB,QAAI,SAAS,SAAU,QAAO,aAAE,OAAO;AACvC,QAAI,SAAS,SAAU,QAAO,aAAE,OAAO;AACvC,QAAI,SAAS,UAAW,QAAO,aAAE,QAAQ;AACzC,QAAI,SAAS,OAAQ,QAAO,aAAE,KAAK;AACnC,QAAI,SAAS,UAAU;AACrB,aAAO,YAAY,MAAM;AAAA,IAC3B;AACA,QAAI,SAAS,SAAS;AACpB,YAAM,WAAW,OAAO;AAAA,QAAQ,CAAC,MAC/B,MAAM,QAAQ,CAAC,IAAI,IAAI,CAAC;AAAA,MAC1B;AACA,UAAI,SAAS,WAAW,EAAG,QAAO,aAAE,MAAM,aAAE,QAAQ,CAAC;AACrD,aAAO,aAAE,MAAM,eAAe,QAAQ,CAAC;AAAA,IACzC;AAAA,EACF;AAGA,MAAI,MAAM,SAAS,KAAK,MAAM,IAAI,QAAQ,GAAG;AAC3C,UAAM,SAAS,IAAI,IAAI,MAAM;AAC7B,QAAI,OAAO,SAAS,GAAG;AACrB,aAAO,aAAE,QAAQ,OAAO,CAAC,CAAW;AAAA,IACtC;AAAA,EACF;AAGA,QAAM,UAA0B,CAAC;AACjC,MAAI,MAAM,IAAI,QAAQ,EAAG,SAAQ,KAAK,aAAE,OAAO,CAAC;AAChD,MAAI,MAAM,IAAI,QAAQ,EAAG,SAAQ,KAAK,aAAE,OAAO,CAAC;AAChD,MAAI,MAAM,IAAI,SAAS,EAAG,SAAQ,KAAK,aAAE,QAAQ,CAAC;AAClD,MAAI,MAAM,IAAI,MAAM,EAAG,SAAQ,KAAK,aAAE,KAAK,CAAC;AAC5C,MAAI,MAAM,IAAI,QAAQ,GAAG;AACvB,UAAM,OAAO,OAAO;AAAA,MAClB,CAAC,MAAM,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAAA,IAChE;AACA,YAAQ,KAAK,YAAY,IAAI,CAAC;AAAA,EAChC;AACA,MAAI,MAAM,IAAI,OAAO,GAAG;AACtB,UAAM,OAAO,OAAO,OAAO,MAAM,OAAO;AACxC,UAAM,WAAW,KAAK,KAAK;AAC3B,YAAQ;AAAA,MACN,aAAE,MAAM,SAAS,SAAS,IAAI,eAAe,QAAQ,IAAI,aAAE,QAAQ,CAAC;AAAA,IACtE;AAAA,EACF;AAEA,MAAI,QAAQ,WAAW,EAAG,QAAO,QAAQ,CAAC;AAC1C,MAAI,QAAQ,WAAW,EAAG,QAAO,aAAE,MAAM,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAQ;AACxE,SAAO,aAAE,MAAM,OAAc;AAC/B;AAEA,SAAS,cAAc,GAAoB;AACzC,MAAI,MAAM,KAAM,QAAO;AACvB,MAAI,MAAM,QAAQ,CAAC,EAAG,QAAO;AAC7B,SAAO,OAAO;AAChB;AAEA,SAAS,oBAAoB,SAAkC;AAC7D,QAAM,QAAQ,IAAI,IAAI,QAAQ,IAAI,aAAa,CAAC;AAChD,QAAM,UAA0B,CAAC;AACjC,MAAI,MAAM,IAAI,QAAQ,EAAG,SAAQ,KAAK,aAAE,OAAO,CAAC;AAChD,MAAI,MAAM,IAAI,QAAQ,EAAG,SAAQ,KAAK,aAAE,OAAO,CAAC;AAChD,MAAI,MAAM,IAAI,SAAS,EAAG,SAAQ,KAAK,aAAE,QAAQ,CAAC;AAClD,MAAI,MAAM,IAAI,MAAM,EAAG,SAAQ,KAAK,aAAE,KAAK,CAAC;AAC5C,MAAI,QAAQ,WAAW,EAAG,QAAO,aAAE,QAAQ;AAC3C,MAAI,QAAQ,WAAW,EAAG,QAAO,QAAQ,CAAC;AAC1C,SAAO,aAAE,MAAM,OAAc;AAC/B;;;AC/LA,IAAAC,cAAkB;AAKX,SAAS,aAAa,QAAsB,SAAS,GAAW;AACrE,QAAM,MAAM,KAAK,OAAO,MAAM;AAE9B,MAAI,kBAAkB,cAAE,UAAW,QAAO;AAC1C,MAAI,kBAAkB,cAAE,UAAW,QAAO;AAC1C,MAAI,kBAAkB,cAAE,WAAY,QAAO;AAC3C,MAAI,kBAAkB,cAAE,QAAS,QAAO;AACxC,MAAI,kBAAkB,cAAE,WAAY,QAAO;AAE3C,MAAI,kBAAkB,cAAE,YAAY;AAClC,UAAM,MAAM,OAAO;AACnB,WAAO,OAAO,QAAQ,WAAW,cAAc,GAAG,OAAO,aAAa,GAAG;AAAA,EAC3E;AAEA,MAAI,kBAAkB,cAAE,UAAU;AAChC,UAAM,QAAQ,aAAa,OAAO,SAAS,MAAM;AACjD,WAAO,WAAW,KAAK;AAAA,EACzB;AAEA,MAAI,kBAAkB,cAAE,WAAW;AACjC,UAAM,QAAQ,OAAO;AACrB,UAAM,OAAO,OAAO,KAAK,KAAK;AAC9B,QAAI,KAAK,WAAW,EAAG,QAAO;AAE9B,UAAM,QAAQ,MAAM;AACpB,UAAM,SAAS,KAAK;AAAA,MAClB,CAAC,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC,CAAC,KAAK,aAAa,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC;AAAA,IACtE;AAEA,UAAM,SACJ,OAAO,QAAS,OAAO,KAAa,gBAAgB,WAChD,cACA;AAEN,WAAO;AAAA,EAAe,OAAO,KAAK,IAAI,CAAC;AAAA,EAAK,GAAG,KAAK,MAAM;AAAA,EAC5D;AAEA,MAAI,kBAAkB,cAAE,UAAU;AAChC,UAAM,OAAQ,OAAe;AAC7B,UAAM,UAAU,KAAK,IAAI,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC;AACvD,QAAI,QAAQ,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,IAAI,CAAC,GAAG;AAC3C,aAAO,YAAY,QAAQ,KAAK,IAAI,CAAC;AAAA,IACvC;AACA,UAAM,QAAQ,MAAM;AACpB,WAAO;AAAA,EAAc,QAAQ,IAAI,CAAC,MAAM,GAAG,KAAK,GAAG,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,EAAK,GAAG;AAAA,EAC7E;AAEA,MAAI,kBAAkB,cAAE,uBAAuB;AAC7C,UAAM,OAAQ,OAAe,KAAK;AAClC,UAAM,OAAQ,OAAe,KAAK;AAClC,UAAM,UAAU,KAAK,IAAI,CAAC,MAAM,aAAa,GAAG,SAAS,CAAC,CAAC;AAC3D,UAAM,QAAQ,MAAM;AACpB,WAAO,yBAAyB,IAAI;AAAA,EAAS,QAAQ,IAAI,CAAC,MAAM,GAAG,KAAK,GAAG,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,EAAK,GAAG;AAAA,EACrG;AAEA,SAAO;AACT;AAEA,SAAS,SAAS,KAAqB;AACrC,SAAO,6BAA6B,KAAK,GAAG,IAAI,MAAM,IAAI,GAAG;AAC/D;","names":["AmplitudeStorage","RedisStorage","import_zod"]}
|
|
1
|
+
{"version":3,"sources":["../src/storage/amplitude.ts","../src/storage/redis.ts","../src/index.ts","../src/storage/memory.ts","../src/storage/resolve.ts","../src/batch-processor.ts","../src/progressive.ts","../src/storage/memory-server.ts","../src/storage/index.ts","../src/infer-schema.ts","../src/schema-to-code.ts"],"sourcesContent":["import type { ProgressiveConfig, StorageBackend } from \"../types.js\";\n\n/**\n * Minimal interface for an Amplitude client.\n * Compatible with @amplitude/analytics-node's `track()` signature.\n * Pass an instance initialized with your observability project's API key\n * (separate from your main product analytics project).\n */\nexport interface AmplitudeClient {\n track(\n eventName: string,\n eventProperties?: Record<string, unknown>,\n options?: { user_id?: string; device_id?: string },\n ): void;\n}\n\n/**\n * Amplitude storage backend for progressive-zod.\n *\n * Sends a single event per type check:\n *\n * \"pzod:type_checked\"\n * - type_name: string — the boundary name passed to progressive()\n * - result: \"conform\" | \"violate\"\n * - sample_type: string — JS typeof the observed value (violate only)\n * - field_count: number — number of top-level keys (violate only, objects)\n * - sample_preview: string — first 256 chars of JSON (violate only)\n * - validation_errors: string — human-readable Zod validation errors (violate only)\n *\n * Read methods (getNames, getSamples, etc.) are no-ops — use the\n * Amplitude dashboard to query your data.\n */\n/**\n * Convert a value into a flat \"key=value; ...\" string so Amplitude\n * treats it as an opaque string instead of exploding JSON keys into\n * separate event properties.\n */\nfunction flattenToString(value: unknown): string {\n if (value === null || value === undefined) return String(value);\n if (typeof value !== \"object\") return String(value);\n if (Array.isArray(value)) return value.map(String).join(\", \");\n const entries = Object.entries(value as Record<string, unknown>);\n return entries.map(([k, v]) => `${k}=${JSON.stringify(v)}`).join(\"; \");\n}\n\nexport class AmplitudeStorage implements StorageBackend {\n private readonly client: AmplitudeClient;\n private readonly deviceId: string;\n\n constructor(\n client: AmplitudeClient,\n config: ProgressiveConfig,\n ) {\n this.client = client;\n // Use a stable device_id so Amplitude groups events from this service\n this.deviceId = `pzod:${config.keyPrefix ?? \"default\"}`;\n }\n\n addName(_name: string): void {\n // No-op: we only track type checks\n }\n\n addSample(_name: string, _sample: string): void {\n // No-op: we only track type checks\n }\n\n addViolation(_name: string, _violation: string): void {\n // No-op: violation data is included in the type_checked event via incrViolate\n }\n\n incrConform(name: string, _sample?: string): void {\n this.client.track(\n \"pzod:type_checked\",\n { type_name: name, result: \"conform\" },\n { device_id: this.deviceId },\n );\n }\n\n incrViolate(name: string, sample?: string, errors?: string): void {\n const properties: Record<string, unknown> = {\n type_name: name,\n result: \"violate\",\n };\n\n if (sample) {\n try {\n const parsed = JSON.parse(sample);\n properties.sample_type = typeof parsed;\n if (parsed && typeof parsed === \"object\" && !Array.isArray(parsed)) {\n properties.field_count = Object.keys(parsed).length;\n }\n // Flatten to key=value pairs so Amplitude doesn't explode JSON into N properties\n properties.sample_preview = flattenToString(parsed).slice(0, 256);\n } catch {\n properties.sample_type = \"unknown\";\n properties.sample_preview = sample.slice(0, 256);\n }\n }\n\n if (errors) {\n properties.validation_errors = errors.slice(0, 1024);\n }\n\n this.client.track(\n \"pzod:type_checked\",\n properties,\n { device_id: this.deviceId },\n );\n }\n\n // --- Read methods: no-ops (use Amplitude dashboard) ---\n\n async getNames(): Promise<string[]> {\n return [];\n }\n\n async getSamples(_name: string): Promise<string[]> {\n return [];\n }\n\n async getViolations(_name: string, _limit: number): Promise<string[]> {\n return [];\n }\n\n async getStats(_name: string): Promise<{ conform: number; violate: number }> {\n return { conform: 0, violate: 0 };\n }\n\n disconnect(): void {\n // Amplitude SDK manages its own lifecycle — nothing to clean up\n }\n}\n","import type { StorageBackend, ProgressiveConfig } from \"../types.js\";\n\n/**\n * Redis storage backend for production use.\n * Requires `ioredis` as a peer dependency.\n */\nexport class RedisStorage implements StorageBackend {\n private redis: any;\n private prefix: string;\n private maxSamples: number;\n private maxViolations: number;\n\n constructor(config: ProgressiveConfig = {}) {\n this.prefix = config.keyPrefix ?? \"pzod:\";\n this.maxSamples = config.maxSamples ?? 1000;\n this.maxViolations = config.maxViolations ?? 1000;\n }\n\n private async getClient(): Promise<any> {\n if (!this.redis) {\n let Redis: any;\n try {\n // Use a variable to prevent consuming bundlers (e.g. Vite) from\n // statically resolving this optional peer dependency.\n const moduleName = \"ioredis\";\n Redis = (await import(moduleName)).default;\n } catch {\n throw new Error(\n \"ioredis is required for Redis storage. Install it with: npm install ioredis\",\n );\n }\n const url =\n process.env.PROGRESSIVE_ZOD_REDIS_URL ?? \"redis://localhost:6379\";\n this.redis = new Redis(url);\n }\n return this.redis;\n }\n\n async addName(name: string): Promise<void> {\n const r = await this.getClient();\n await r.sadd(`${this.prefix}names`, name).catch(() => {});\n }\n\n async addSample(name: string, sample: string): Promise<void> {\n const r = await this.getClient();\n const p = r.pipeline();\n p.lpush(`${this.prefix}${name}:samples`, sample);\n p.ltrim(`${this.prefix}${name}:samples`, 0, this.maxSamples - 1);\n await p.exec().catch(() => {});\n }\n\n async addViolation(name: string, violation: string): Promise<void> {\n const r = await this.getClient();\n const p = r.pipeline();\n p.lpush(`${this.prefix}${name}:violations`, violation);\n p.ltrim(`${this.prefix}${name}:violations`, 0, this.maxViolations - 1);\n await p.exec().catch(() => {});\n }\n\n async incrConform(name: string): Promise<void> {\n const r = await this.getClient();\n await r.incr(`${this.prefix}${name}:conform`).catch(() => {});\n }\n\n async incrViolate(name: string): Promise<void> {\n const r = await this.getClient();\n await r.incr(`${this.prefix}${name}:violate`).catch(() => {});\n }\n\n async getNames(): Promise<string[]> {\n const r = await this.getClient();\n const names = await r.smembers(`${this.prefix}names`);\n return names.sort();\n }\n\n async getSamples(name: string): Promise<string[]> {\n const r = await this.getClient();\n return r.lrange(`${this.prefix}${name}:samples`, 0, -1);\n }\n\n async getViolations(name: string, limit: number): Promise<string[]> {\n const r = await this.getClient();\n return r.lrange(`${this.prefix}${name}:violations`, 0, limit - 1);\n }\n\n async getStats(\n name: string,\n ): Promise<{ conform: number; violate: number }> {\n const r = await this.getClient();\n const [conform, violate] = await Promise.all([\n r.get(`${this.prefix}${name}:conform`),\n r.get(`${this.prefix}${name}:violate`),\n ]);\n return {\n conform: parseInt(conform ?? \"0\", 10),\n violate: parseInt(violate ?? \"0\", 10),\n };\n }\n\n async disconnect(): Promise<void> {\n if (this.redis) {\n await this.redis.quit();\n this.redis = null;\n }\n }\n}\n","export { progressive, configureBatch, forceFlush, shutdown } from \"./progressive.js\";\nexport { configure } from \"./storage/index.js\";\nexport { inferSchema } from \"./infer-schema.js\";\nexport { schemaToCode } from \"./schema-to-code.js\";\nexport type { ProgressiveConfig, ProgressiveSchema, StorageBackend } from \"./types.js\";\nexport type { BatchConfig } from \"./batch-processor.js\";\nexport type { AmplitudeClient } from \"./storage/amplitude.js\";\n","import type { StorageBackend, ProgressiveConfig } from \"../types.js\";\n\ninterface TypeData {\n samples: string[];\n violations: string[];\n conform: number;\n violate: number;\n}\n\n/**\n * In-memory storage backend.\n * No Node.js built-in dependencies — safe for browser bundles.\n */\nexport class MemoryStorage implements StorageBackend {\n protected names = new Set<string>();\n protected data = new Map<string, TypeData>();\n protected maxSamples: number;\n protected maxViolations: number;\n\n constructor(config: ProgressiveConfig = {}) {\n this.maxSamples = config.maxSamples ?? 1000;\n this.maxViolations = config.maxViolations ?? 1000;\n }\n\n protected getOrCreate(name: string): TypeData {\n let entry = this.data.get(name);\n if (!entry) {\n entry = { samples: [], violations: [], conform: 0, violate: 0 };\n this.data.set(name, entry);\n }\n return entry;\n }\n\n addName(name: string): void {\n this.names.add(name);\n }\n\n addSample(name: string, sample: string): void {\n const entry = this.getOrCreate(name);\n entry.samples.unshift(sample);\n if (entry.samples.length > this.maxSamples) {\n entry.samples.length = this.maxSamples;\n }\n }\n\n addViolation(name: string, violation: string): void {\n const entry = this.getOrCreate(name);\n entry.violations.unshift(violation);\n if (entry.violations.length > this.maxViolations) {\n entry.violations.length = this.maxViolations;\n }\n }\n\n incrConform(name: string): void {\n this.getOrCreate(name).conform++;\n }\n\n incrViolate(name: string): void {\n this.getOrCreate(name).violate++;\n }\n\n getNames(): string[] {\n return [...this.names].sort();\n }\n\n getSamples(name: string): string[] {\n return this.getOrCreate(name).samples;\n }\n\n getViolations(name: string, limit: number): string[] {\n return this.getOrCreate(name).violations.slice(0, limit);\n }\n\n async getStats(name: string): Promise<{ conform: number; violate: number }> {\n const entry = this.getOrCreate(name);\n return { conform: entry.conform, violate: entry.violate };\n }\n\n disconnect(): void {\n // No-op for pure in-memory storage\n }\n}\n","import type { ProgressiveConfig, StorageBackend } from \"../types.js\";\nimport { MemoryStorage } from \"./memory.js\";\n\nlet currentConfig: ProgressiveConfig = {};\nlet currentStorage: StorageBackend | null = null;\n\nexport type StorageFactory = (\n resolvedConfig: ProgressiveConfig,\n userConfig: ProgressiveConfig,\n) => Promise<StorageBackend>;\n\n// Default factory: memory-only (safe for any environment)\nlet storageFactory: StorageFactory = async (config) => new MemoryStorage(config);\n\n/**\n * Register a storage factory. Called by entry-point modules\n * (storage/index.ts for server, storage/client.ts for client)\n * to control which backends are available.\n */\nexport function _setStorageFactory(factory: StorageFactory): void {\n storageFactory = factory;\n}\n\nexport function configure(config: ProgressiveConfig): void {\n currentConfig = { ...currentConfig, ...config };\n // Force re-creation on next access\n if (currentStorage) {\n currentStorage.disconnect();\n currentStorage = null;\n }\n}\n\nfunction env(key: string): string | undefined {\n if (typeof process !== \"undefined\" && process.env) {\n return process.env[key];\n }\n return undefined;\n}\n\nexport function getConfig(): ProgressiveConfig {\n return {\n storage: currentConfig.storage ?? (env(\"PROGRESSIVE_ZOD_STORAGE\") as any) ?? \"memory\",\n redisUrl: currentConfig.redisUrl ?? env(\"PROGRESSIVE_ZOD_REDIS_URL\"),\n keyPrefix: currentConfig.keyPrefix ?? env(\"PROGRESSIVE_ZOD_KEY_PREFIX\") ?? \"pzod:\",\n maxViolations: currentConfig.maxViolations ?? parseInt(env(\"PROGRESSIVE_ZOD_MAX_VIOLATIONS\") ?? \"1000\", 10),\n maxSamples: currentConfig.maxSamples ?? parseInt(env(\"PROGRESSIVE_ZOD_MAX_SAMPLES\") ?? \"1000\", 10),\n dataDir: currentConfig.dataDir ?? env(\"PROGRESSIVE_ZOD_DATA_DIR\"),\n };\n}\n\nexport async function getStorage(): Promise<StorageBackend> {\n if (currentStorage) return currentStorage;\n\n const config = getConfig();\n currentStorage = await storageFactory(config, currentConfig);\n return currentStorage;\n}\n\nexport async function disconnectStorage(): Promise<void> {\n if (currentStorage) {\n await currentStorage.disconnect();\n currentStorage = null;\n }\n}\n","import type { z } from \"zod\";\nimport type { StorageBackend } from \"./types.js\";\nimport { getStorage } from \"./storage/resolve.js\";\n\nexport interface BatchConfig {\n /** Max observations to buffer before forcing a flush. Default: 512 */\n maxQueueSize?: number;\n /** Flush interval in milliseconds. Default: 5000 */\n flushIntervalMs?: number;\n /** Max observations to export per flush. Default: 512 */\n maxExportBatchSize?: number;\n}\n\ninterface Observation {\n name: string;\n serialized: string;\n schema?: z.ZodTypeAny;\n}\n\nconst DEFAULT_MAX_QUEUE_SIZE = 2048;\nconst DEFAULT_FLUSH_INTERVAL_MS = 5000;\nconst DEFAULT_MAX_EXPORT_BATCH_SIZE = 512;\n\nexport class BatchProcessor {\n private queue: Observation[] = [];\n private timer: ReturnType<typeof setInterval> | null = null;\n private flushing = false;\n private droppedCount = 0;\n\n private readonly maxQueueSize: number;\n private readonly flushIntervalMs: number;\n private readonly maxExportBatchSize: number;\n\n constructor(config: BatchConfig = {}) {\n this.maxQueueSize = config.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE;\n this.flushIntervalMs = config.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;\n this.maxExportBatchSize = config.maxExportBatchSize ?? DEFAULT_MAX_EXPORT_BATCH_SIZE;\n }\n\n /**\n * Enqueue an observation. This is synchronous and fast — no I/O happens here.\n * If the queue is full, the oldest observation is dropped (bounded memory).\n */\n enqueue(name: string, input: unknown, schema?: z.ZodTypeAny): void {\n this.ensureTimer();\n\n let serialized: string;\n try {\n serialized = JSON.stringify(input);\n } catch {\n // Non-serializable input — skip silently\n return;\n }\n\n if (this.queue.length >= this.maxQueueSize) {\n // Drop oldest to stay within bounds\n this.queue.shift();\n this.droppedCount++;\n }\n\n this.queue.push({ name, serialized, schema });\n\n // Flush immediately if we've hit the export batch size\n if (this.queue.length >= this.maxExportBatchSize) {\n this.flushAsync();\n }\n }\n\n /**\n * Force flush all pending observations. Call during graceful shutdown.\n */\n async forceFlush(): Promise<void> {\n this.clearTimer();\n await this.flush();\n }\n\n /**\n * Shut down the processor: flush remaining data and stop the timer.\n */\n async shutdown(): Promise<void> {\n await this.forceFlush();\n }\n\n /** Number of observations currently in the queue */\n get pendingCount(): number {\n return this.queue.length;\n }\n\n /** Number of observations dropped due to queue overflow */\n get dropped(): number {\n return this.droppedCount;\n }\n\n private ensureTimer(): void {\n if (this.timer) return;\n this.timer = setInterval(() => {\n this.flushAsync();\n }, this.flushIntervalMs);\n // Don't keep the process alive just for telemetry\n if (this.timer && typeof this.timer === \"object\" && \"unref\" in this.timer) {\n this.timer.unref();\n }\n }\n\n private clearTimer(): void {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = null;\n }\n }\n\n /** Non-blocking flush — errors are swallowed */\n private flushAsync(): void {\n this.flush().catch(() => {});\n }\n\n /** Drain the queue and send observations to storage in batch */\n private async flush(): Promise<void> {\n if (this.flushing || this.queue.length === 0) return;\n this.flushing = true;\n\n // Drain up to maxExportBatchSize\n const batch = this.queue.splice(0, this.maxExportBatchSize);\n\n try {\n const storage = await getStorage();\n await this.exportBatch(storage, batch);\n } catch {\n // Swallow errors — observability must never crash the app\n } finally {\n this.flushing = false;\n // If items accumulated during flush, schedule another\n if (this.queue.length >= this.maxExportBatchSize) {\n this.flushAsync();\n }\n }\n }\n\n private async exportBatch(\n storage: StorageBackend,\n batch: Observation[],\n ): Promise<void> {\n // Collect unique names first\n const names = new Set<string>();\n for (const obs of batch) {\n names.add(obs.name);\n }\n\n // Register all names\n await Promise.all([...names].map((n) => storage.addName(n)));\n\n // Process each observation\n // We batch the promises to avoid creating thousands of concurrent promises\n const promises: Promise<void>[] = [];\n\n for (const obs of batch) {\n promises.push(this.exportOne(storage, obs));\n }\n\n await Promise.all(promises);\n }\n\n private async exportOne(\n storage: StorageBackend,\n obs: Observation,\n ): Promise<void> {\n await storage.addSample(obs.name, obs.serialized);\n\n if (obs.schema) {\n const result = obs.schema.safeParse(JSON.parse(obs.serialized));\n if (result.success) {\n await storage.incrConform(obs.name, obs.serialized);\n } else {\n const errors = result.error.issues\n .map((i) => {\n const path = i.path.length > 0 ? i.path.join(\".\") : \"(root)\";\n return `${path}: ${i.message}`;\n })\n .join(\"; \");\n await storage.incrViolate(obs.name, obs.serialized, errors);\n await storage.addViolation(obs.name, obs.serialized);\n }\n } else {\n await storage.incrViolate(obs.name, obs.serialized, \"no schema defined\");\n await storage.addViolation(obs.name, obs.serialized);\n }\n }\n}\n","import type { z } from \"zod\";\nimport type { ProgressiveSchema } from \"./types.js\";\nimport { BatchProcessor } from \"./batch-processor.js\";\nimport type { BatchConfig } from \"./batch-processor.js\";\n\nlet processor: BatchProcessor | null = null;\n\nfunction getProcessor(): BatchProcessor {\n if (!processor) {\n processor = new BatchProcessor();\n }\n return processor;\n}\n\n/**\n * Configure the batch processor. Call before first `progressive()` use.\n * Follows the OpenTelemetry provider pattern:\n * - Observations are buffered in memory (synchronous, zero I/O on hot path)\n * - Flushed to storage in batches on a timer or when buffer is full\n * - Queue is bounded to prevent memory leaks\n * - Timer is unref'd so it won't keep the process alive\n */\nexport function configureBatch(config: BatchConfig): void {\n if (processor) {\n // Flush existing before reconfiguring\n processor.forceFlush().catch(() => {});\n }\n processor = new BatchProcessor(config);\n}\n\n/**\n * Force flush all pending observations. Call during graceful shutdown.\n *\n * @example\n * ```ts\n * process.on(\"SIGTERM\", async () => {\n * await forceFlush();\n * process.exit(0);\n * });\n * ```\n */\nexport async function forceFlush(): Promise<void> {\n if (processor) {\n await processor.forceFlush();\n }\n}\n\n/**\n * Shut down the batch processor and flush remaining data.\n */\nexport async function shutdown(): Promise<void> {\n if (processor) {\n await processor.shutdown();\n processor = null;\n }\n}\n\n/**\n * Create a progressive schema that tracks runtime data and optionally validates.\n *\n * - Never throws — always returns input unchanged\n * - Records samples for later schema inference\n * - If a schema is provided, tracks conformance vs violations\n * - Observations are batched and flushed asynchronously (OTel-style)\n * - Zero I/O on the hot path — enqueue is synchronous\n */\nexport function progressive(\n name: string,\n schema?: z.ZodTypeAny,\n): ProgressiveSchema {\n return {\n parse(input: unknown): unknown {\n // Synchronous enqueue — no I/O, no promises, no overhead\n getProcessor().enqueue(name, input, schema);\n return input;\n },\n };\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport type { ProgressiveConfig } from \"../types.js\";\nimport { MemoryStorage } from \"./memory.js\";\n\n/**\n * In-memory storage with optional file persistence.\n * Uses Node.js fs/path — server-only, not safe for browser bundles.\n */\nexport class PersistentMemoryStorage extends MemoryStorage {\n private dataDir: string | undefined;\n private flushTimer: ReturnType<typeof setTimeout> | undefined;\n\n constructor(config: ProgressiveConfig = {}) {\n super(config);\n this.dataDir = config.dataDir;\n if (this.dataDir) {\n this.loadFromDisk();\n }\n }\n\n override addName(name: string): void {\n super.addName(name);\n this.schedulePersist();\n }\n\n override addSample(name: string, sample: string): void {\n super.addSample(name, sample);\n this.schedulePersist();\n }\n\n override addViolation(name: string, violation: string): void {\n super.addViolation(name, violation);\n this.schedulePersist();\n }\n\n override incrConform(name: string): void {\n super.incrConform(name);\n this.schedulePersist();\n }\n\n override incrViolate(name: string): void {\n super.incrViolate(name);\n this.schedulePersist();\n }\n\n override disconnect(): void {\n if (this.flushTimer) {\n clearTimeout(this.flushTimer);\n this.flushTimer = undefined;\n }\n if (this.dataDir) {\n this.persistToDisk();\n }\n }\n\n private schedulePersist(): void {\n if (!this.dataDir || this.flushTimer) return;\n this.flushTimer = setTimeout(() => {\n this.flushTimer = undefined;\n this.persistToDisk();\n }, 500);\n }\n\n private persistToDisk(): void {\n if (!this.dataDir) return;\n try {\n fs.mkdirSync(this.dataDir, { recursive: true });\n const snapshot = {\n names: [...this.names],\n types: Object.fromEntries(this.data),\n };\n fs.writeFileSync(\n path.join(this.dataDir, \"data.json\"),\n JSON.stringify(snapshot, null, 2),\n );\n } catch {\n // fire-and-forget — never crash the app\n }\n }\n\n private loadFromDisk(): void {\n if (!this.dataDir) return;\n try {\n const raw = fs.readFileSync(\n path.join(this.dataDir, \"data.json\"),\n \"utf-8\",\n );\n const snapshot = JSON.parse(raw);\n if (Array.isArray(snapshot.names)) {\n for (const n of snapshot.names) this.names.add(n);\n }\n if (snapshot.types && typeof snapshot.types === \"object\") {\n for (const [key, val] of Object.entries(snapshot.types)) {\n this.data.set(key, val as { samples: string[]; violations: string[]; conform: number; violate: number });\n }\n }\n } catch {\n // no data yet — that's fine\n }\n }\n}\n","import { _setStorageFactory } from \"./resolve.js\";\nimport { PersistentMemoryStorage } from \"./memory-server.js\";\n\n// Register server storage factory — supports all backends including Redis\n_setStorageFactory(async (config, userConfig) => {\n if (config.storage === \"amplitude\") {\n if (!userConfig.amplitudeClient) {\n throw new Error(\n \"progressive-zod: storage is set to 'amplitude' but no amplitudeClient was provided. \" +\n \"Pass an Amplitude client instance via configure({ amplitudeClient }).\",\n );\n }\n const { AmplitudeStorage } = await import(\"./amplitude.js\");\n return new AmplitudeStorage(userConfig.amplitudeClient, config);\n } else if (config.storage === \"redis\") {\n // Dynamic import so ioredis isn't loaded unless needed\n const { RedisStorage } = await import(\"./redis.js\");\n return new RedisStorage(config);\n }\n\n // Default to file persistence in server environment\n const serverConfig = { ...config, dataDir: config.dataDir ?? \".progressive-zod\" };\n return new PersistentMemoryStorage(serverConfig);\n});\n\nexport { configure, getConfig, getStorage, disconnectStorage } from \"./resolve.js\";\n","import { z } from \"zod\";\n\n/**\n * Infer a Zod schema from an array of runtime samples.\n */\nexport function inferSchema(samples: unknown[]): z.ZodTypeAny {\n const objects = samples.filter(\n (s): s is Record<string, unknown> =>\n typeof s === \"object\" && s !== null && !Array.isArray(s),\n );\n\n if (objects.length === 0) {\n return inferPrimitiveUnion(samples);\n }\n\n // Group samples by their shape (set of keys)\n const groups = groupByShape(objects);\n\n if (groups.length === 1) {\n return buildObjectSchema(groups[0]);\n }\n\n // Try to find a discriminator field\n const discriminator = findDiscriminator(groups);\n if (discriminator) {\n return z.discriminatedUnion(\n discriminator,\n groups.map(\n (group) => buildObjectSchema(group) as z.ZodObject<any>,\n ) as any,\n );\n }\n\n return z.union(\n groups.map((group) => buildObjectSchema(group)) as any,\n );\n}\n\nfunction shapeKey(obj: Record<string, unknown>): string {\n return Object.keys(obj).sort().join(\",\");\n}\n\nfunction groupByShape(\n objects: Record<string, unknown>[],\n): Record<string, unknown>[][] {\n const map = new Map<string, Record<string, unknown>[]>();\n for (const obj of objects) {\n const key = shapeKey(obj);\n let group = map.get(key);\n if (!group) {\n group = [];\n map.set(key, group);\n }\n group.push(obj);\n }\n return [...map.values()];\n}\n\nfunction findDiscriminator(\n groups: Record<string, unknown>[][],\n): string | null {\n if (groups.length < 2) return null;\n\n // Get keys present in all groups\n const keySets = groups.map(\n (g) => new Set(Object.keys(g[0])),\n );\n const commonKeys = [...keySets[0]].filter((k) =>\n keySets.every((s) => s.has(k)),\n );\n\n for (const key of commonKeys) {\n // Check if this key has a single string literal value per group\n // and the values are distinct across groups\n const values = new Set<string>();\n let valid = true;\n\n for (const group of groups) {\n const groupValues = new Set(\n group.map((obj) => obj[key]).filter((v) => typeof v === \"string\"),\n );\n if (groupValues.size !== 1) {\n valid = false;\n break;\n }\n const val = [...groupValues][0] as string;\n if (values.has(val)) {\n valid = false;\n break;\n }\n values.add(val);\n }\n\n if (valid && values.size === groups.length) {\n return key;\n }\n }\n\n return null;\n}\n\nfunction buildObjectSchema(\n samples: Record<string, unknown>[],\n): z.ZodObject<any> {\n const keys = Object.keys(samples[0]);\n const shape: Record<string, z.ZodTypeAny> = {};\n\n for (const key of keys) {\n const values = samples.map((s) => s[key]);\n // If all values are the same string, use z.literal() (needed for discriminated unions)\n const unique = new Set(values);\n if (unique.size === 1 && typeof values[0] === \"string\") {\n shape[key] = z.literal(values[0] as string);\n } else {\n shape[key] = inferFieldType(values);\n }\n }\n\n return z.object(shape).strict();\n}\n\nfunction inferFieldType(values: unknown[]): z.ZodTypeAny {\n const types = new Set(values.map(classifyValue));\n\n if (types.size === 1) {\n const type = [...types][0];\n if (type === \"string\") return z.string();\n if (type === \"number\") return z.number();\n if (type === \"boolean\") return z.boolean();\n if (type === \"null\") return z.null();\n if (type === \"object\") {\n return inferSchema(values);\n }\n if (type === \"array\") {\n const allItems = values.flatMap((v) =>\n Array.isArray(v) ? v : [],\n );\n if (allItems.length === 0) return z.array(z.unknown());\n return z.array(inferFieldType(allItems));\n }\n }\n\n // Check if it's string literal values (for discriminator fields)\n if (types.size === 1 && types.has(\"string\")) {\n const unique = new Set(values);\n if (unique.size === 1) {\n return z.literal(values[0] as string);\n }\n }\n\n // Mixed types — build a union\n const members: z.ZodTypeAny[] = [];\n if (types.has(\"string\")) members.push(z.string());\n if (types.has(\"number\")) members.push(z.number());\n if (types.has(\"boolean\")) members.push(z.boolean());\n if (types.has(\"null\")) members.push(z.null());\n if (types.has(\"object\")) {\n const objs = values.filter(\n (v) => typeof v === \"object\" && v !== null && !Array.isArray(v),\n );\n members.push(inferSchema(objs));\n }\n if (types.has(\"array\")) {\n const arrs = values.filter(Array.isArray);\n const allItems = arrs.flat();\n members.push(\n z.array(allItems.length > 0 ? inferFieldType(allItems) : z.unknown()),\n );\n }\n\n if (members.length === 1) return members[0];\n if (members.length === 2) return z.union([members[0], members[1]] as any);\n return z.union(members as any);\n}\n\nfunction classifyValue(v: unknown): string {\n if (v === null) return \"null\";\n if (Array.isArray(v)) return \"array\";\n return typeof v;\n}\n\nfunction inferPrimitiveUnion(samples: unknown[]): z.ZodTypeAny {\n const types = new Set(samples.map(classifyValue));\n const members: z.ZodTypeAny[] = [];\n if (types.has(\"string\")) members.push(z.string());\n if (types.has(\"number\")) members.push(z.number());\n if (types.has(\"boolean\")) members.push(z.boolean());\n if (types.has(\"null\")) members.push(z.null());\n if (members.length === 0) return z.unknown();\n if (members.length === 1) return members[0];\n return z.union(members as any);\n}\n","import { z } from \"zod\";\n\n/**\n * Convert a Zod schema into readable TypeScript code that recreates it.\n */\nexport function schemaToCode(schema: z.ZodTypeAny, indent = 0): string {\n const pad = \" \".repeat(indent);\n\n if (schema instanceof z.ZodString) return \"z.string()\";\n if (schema instanceof z.ZodNumber) return \"z.number()\";\n if (schema instanceof z.ZodBoolean) return \"z.boolean()\";\n if (schema instanceof z.ZodNull) return \"z.null()\";\n if (schema instanceof z.ZodUnknown) return \"z.unknown()\";\n\n if (schema instanceof z.ZodLiteral) {\n const val = schema.value;\n return typeof val === \"string\" ? `z.literal(\"${val}\")` : `z.literal(${val})`;\n }\n\n if (schema instanceof z.ZodArray) {\n const inner = schemaToCode(schema.element, indent);\n return `z.array(${inner})`;\n }\n\n if (schema instanceof z.ZodObject) {\n const shape = schema.shape as Record<string, z.ZodTypeAny>;\n const keys = Object.keys(shape);\n if (keys.length === 0) return \"z.object({})\";\n\n const inner = pad + \" \";\n const fields = keys.map(\n (k) => `${inner}${safeProp(k)}: ${schemaToCode(shape[k], indent + 1)},`,\n );\n\n const strict =\n schema._def && (schema._def as any).unknownKeys === \"strict\"\n ? \".strict()\"\n : \"\";\n\n return `z.object({\\n${fields.join(\"\\n\")}\\n${pad}})${strict}`;\n }\n\n if (schema instanceof z.ZodUnion) {\n const opts = (schema as any).options as z.ZodTypeAny[];\n const members = opts.map((o) => schemaToCode(o, indent));\n if (members.every((m) => !m.includes(\"\\n\"))) {\n return `z.union([${members.join(\", \")}])`;\n }\n const inner = pad + \" \";\n return `z.union([\\n${members.map((m) => `${inner}${m},`).join(\"\\n\")}\\n${pad}])`;\n }\n\n if (schema instanceof z.ZodDiscriminatedUnion) {\n const disc = (schema as any)._def.discriminator as string;\n const opts = (schema as any)._def.options as z.ZodTypeAny[];\n const members = opts.map((o) => schemaToCode(o, indent + 1));\n const inner = pad + \" \";\n return `z.discriminatedUnion(\"${disc}\", [\\n${members.map((m) => `${inner}${m},`).join(\"\\n\")}\\n${pad}])`;\n }\n\n return \"z.unknown()\";\n}\n\nfunction safeProp(key: string): string {\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : `\"${key}\"`;\n}\n"],"mappings":"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","names":["path","AmplitudeStorage","RedisStorage","import_zod"]}
|