@holonograph/client 0.2.0 → 0.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/dist/index.d.ts +321 -152
- package/dist/index.js +689 -13
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4691,7 +4691,9 @@ var LightSnapshotSchema = external_exports.object({
|
|
|
4691
4691
|
|
|
4692
4692
|
vendorMetadata: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
|
|
4693
4693
|
|
|
4694
|
-
rawRequestOmitted: external_exports.boolean().optional()
|
|
4694
|
+
rawRequestOmitted: external_exports.boolean().optional(),
|
|
4695
|
+
|
|
4696
|
+
rawResponsePresence: external_exports.enum(["present", "omitted-by-policy", "pending-attach", "failed-attach"]).optional()
|
|
4695
4697
|
});
|
|
4696
4698
|
var DimensionResultSchema = external_exports.object({
|
|
4697
4699
|
dimensionId: DimensionIdSchema,
|
|
@@ -4765,7 +4767,9 @@ var EvaluationEventKindSchema = external_exports.enum([
|
|
|
4765
4767
|
|
|
4766
4768
|
"analysis.eval-recommendation",
|
|
4767
4769
|
|
|
4768
|
-
"analysis.conformance-fixture"
|
|
4770
|
+
"analysis.conformance-fixture",
|
|
4771
|
+
|
|
4772
|
+
"analysis.emission-coverage"
|
|
4769
4773
|
]);
|
|
4770
4774
|
var AvailabilityTransitionDirectionSchema = external_exports.enum([
|
|
4771
4775
|
"reachable->unreachable",
|
|
@@ -4941,6 +4945,18 @@ var ConformanceFixtureRecordSchema = external_exports.object({
|
|
|
4941
4945
|
|
|
4942
4946
|
sourceSurfaceId: external_exports.string().min(1).optional()
|
|
4943
4947
|
});
|
|
4948
|
+
var EmissionCoverageSchema = external_exports.object({
|
|
4949
|
+
|
|
4950
|
+
streamId: external_exports.string().min(1),
|
|
4951
|
+
|
|
4952
|
+
observedOrdinals: external_exports.array(external_exports.number().int().nonnegative()),
|
|
4953
|
+
|
|
4954
|
+
sentinelHighWater: external_exports.number().int().nonnegative().nullable(),
|
|
4955
|
+
|
|
4956
|
+
finalSeen: external_exports.boolean(),
|
|
4957
|
+
|
|
4958
|
+
observedAtMs: external_exports.number().int().nonnegative()
|
|
4959
|
+
});
|
|
4944
4960
|
var EvaluationEventSchema = external_exports.object({
|
|
4945
4961
|
|
|
4946
4962
|
eventId: external_exports.string().min(1),
|
|
@@ -4971,31 +4987,36 @@ var EvaluationEventSchema = external_exports.object({
|
|
|
4971
4987
|
|
|
4972
4988
|
evalRecommendation: EvalRecommendationSchema.optional(),
|
|
4973
4989
|
|
|
4974
|
-
conformanceFixtureRecord: ConformanceFixtureRecordSchema.optional()
|
|
4990
|
+
conformanceFixtureRecord: ConformanceFixtureRecordSchema.optional(),
|
|
4991
|
+
|
|
4992
|
+
emissionCoverage: EmissionCoverageSchema.optional()
|
|
4975
4993
|
}).refine(
|
|
4976
4994
|
(e) => {
|
|
4977
4995
|
if (e.kind === "evaluation") {
|
|
4978
|
-
return e.light !== void 0 && e.substrate !== void 0 && e.surface !== void 0 && e.availability === void 0 && e.noiseFloorCalibration === void 0 && e.varianceDecomposition === void 0 && e.lifecycleTransition === void 0 && e.evalRecommendation === void 0 && e.conformanceFixtureRecord === void 0;
|
|
4996
|
+
return e.light !== void 0 && e.substrate !== void 0 && e.surface !== void 0 && e.availability === void 0 && e.noiseFloorCalibration === void 0 && e.varianceDecomposition === void 0 && e.lifecycleTransition === void 0 && e.evalRecommendation === void 0 && e.conformanceFixtureRecord === void 0 && e.emissionCoverage === void 0;
|
|
4979
4997
|
}
|
|
4980
4998
|
if (e.kind === "availability.transition") {
|
|
4981
|
-
return e.availability !== void 0 && e.light === void 0 && e.substrate === void 0 && e.surface === void 0 && e.noiseFloorCalibration === void 0 && e.varianceDecomposition === void 0 && e.lifecycleTransition === void 0 && e.evalRecommendation === void 0 && e.conformanceFixtureRecord === void 0;
|
|
4999
|
+
return e.availability !== void 0 && e.light === void 0 && e.substrate === void 0 && e.surface === void 0 && e.noiseFloorCalibration === void 0 && e.varianceDecomposition === void 0 && e.lifecycleTransition === void 0 && e.evalRecommendation === void 0 && e.conformanceFixtureRecord === void 0 && e.emissionCoverage === void 0;
|
|
4982
5000
|
}
|
|
4983
5001
|
if (e.kind === "analysis.noise-floor-calibration") {
|
|
4984
|
-
return e.noiseFloorCalibration !== void 0 && e.light === void 0 && e.substrate === void 0 && e.surface === void 0 && e.availability === void 0 && e.varianceDecomposition === void 0 && e.lifecycleTransition === void 0 && e.evalRecommendation === void 0 && e.conformanceFixtureRecord === void 0;
|
|
5002
|
+
return e.noiseFloorCalibration !== void 0 && e.light === void 0 && e.substrate === void 0 && e.surface === void 0 && e.availability === void 0 && e.varianceDecomposition === void 0 && e.lifecycleTransition === void 0 && e.evalRecommendation === void 0 && e.conformanceFixtureRecord === void 0 && e.emissionCoverage === void 0;
|
|
4985
5003
|
}
|
|
4986
5004
|
if (e.kind === "analysis.variance-decomposition") {
|
|
4987
|
-
return e.varianceDecomposition !== void 0 && e.light === void 0 && e.substrate === void 0 && e.surface === void 0 && e.availability === void 0 && e.noiseFloorCalibration === void 0 && e.lifecycleTransition === void 0 && e.evalRecommendation === void 0 && e.conformanceFixtureRecord === void 0;
|
|
5005
|
+
return e.varianceDecomposition !== void 0 && e.light === void 0 && e.substrate === void 0 && e.surface === void 0 && e.availability === void 0 && e.noiseFloorCalibration === void 0 && e.lifecycleTransition === void 0 && e.evalRecommendation === void 0 && e.conformanceFixtureRecord === void 0 && e.emissionCoverage === void 0;
|
|
4988
5006
|
}
|
|
4989
5007
|
if (e.kind === "analysis.lifecycle-transition") {
|
|
4990
|
-
return e.lifecycleTransition !== void 0 && e.light === void 0 && e.substrate === void 0 && e.surface === void 0 && e.availability === void 0 && e.noiseFloorCalibration === void 0 && e.varianceDecomposition === void 0 && e.evalRecommendation === void 0 && e.conformanceFixtureRecord === void 0;
|
|
5008
|
+
return e.lifecycleTransition !== void 0 && e.light === void 0 && e.substrate === void 0 && e.surface === void 0 && e.availability === void 0 && e.noiseFloorCalibration === void 0 && e.varianceDecomposition === void 0 && e.evalRecommendation === void 0 && e.conformanceFixtureRecord === void 0 && e.emissionCoverage === void 0;
|
|
4991
5009
|
}
|
|
4992
5010
|
if (e.kind === "analysis.eval-recommendation") {
|
|
4993
|
-
return e.evalRecommendation !== void 0 && e.light === void 0 && e.substrate === void 0 && e.surface === void 0 && e.availability === void 0 && e.noiseFloorCalibration === void 0 && e.varianceDecomposition === void 0 && e.lifecycleTransition === void 0 && e.conformanceFixtureRecord === void 0;
|
|
5011
|
+
return e.evalRecommendation !== void 0 && e.light === void 0 && e.substrate === void 0 && e.surface === void 0 && e.availability === void 0 && e.noiseFloorCalibration === void 0 && e.varianceDecomposition === void 0 && e.lifecycleTransition === void 0 && e.conformanceFixtureRecord === void 0 && e.emissionCoverage === void 0;
|
|
5012
|
+
}
|
|
5013
|
+
if (e.kind === "analysis.conformance-fixture") {
|
|
5014
|
+
return e.conformanceFixtureRecord !== void 0 && e.light === void 0 && e.substrate === void 0 && e.surface === void 0 && e.availability === void 0 && e.noiseFloorCalibration === void 0 && e.varianceDecomposition === void 0 && e.lifecycleTransition === void 0 && e.evalRecommendation === void 0 && e.emissionCoverage === void 0;
|
|
4994
5015
|
}
|
|
4995
|
-
return e.
|
|
5016
|
+
return e.emissionCoverage !== void 0 && e.light === void 0 && e.substrate === void 0 && e.surface === void 0 && e.availability === void 0 && e.noiseFloorCalibration === void 0 && e.varianceDecomposition === void 0 && e.lifecycleTransition === void 0 && e.evalRecommendation === void 0 && e.conformanceFixtureRecord === void 0;
|
|
4996
5017
|
},
|
|
4997
5018
|
{
|
|
4998
|
-
message: "EvaluationEvent shape invariant: each kind requires exactly its corresponding payload and forbids the others. kind='evaluation' \u2192 light+substrate+surface; kind='availability.transition' \u2192 availability; kind='analysis.noise-floor-calibration' \u2192 noiseFloorCalibration; kind='analysis.variance-decomposition' \u2192 varianceDecomposition; kind='analysis.lifecycle-transition' \u2192 lifecycleTransition; kind='analysis.eval-recommendation' \u2192 evalRecommendation; kind='analysis.conformance-fixture' \u2192 conformanceFixtureRecord."
|
|
5019
|
+
message: "EvaluationEvent shape invariant: each kind requires exactly its corresponding payload and forbids the others. kind='evaluation' \u2192 light+substrate+surface; kind='availability.transition' \u2192 availability; kind='analysis.noise-floor-calibration' \u2192 noiseFloorCalibration; kind='analysis.variance-decomposition' \u2192 varianceDecomposition; kind='analysis.lifecycle-transition' \u2192 lifecycleTransition; kind='analysis.eval-recommendation' \u2192 evalRecommendation; kind='analysis.conformance-fixture' \u2192 conformanceFixtureRecord; kind='analysis.emission-coverage' \u2192 emissionCoverage."
|
|
4999
5020
|
}
|
|
5000
5021
|
);
|
|
5001
5022
|
function newEventId(occurredAt = new Date()) {
|
|
@@ -5310,6 +5331,596 @@ var InProcessTransport = class {
|
|
|
5310
5331
|
}
|
|
5311
5332
|
};
|
|
5312
5333
|
|
|
5334
|
+
var BoundedEmitBuffer = class {
|
|
5335
|
+
capacity;
|
|
5336
|
+
items = [];
|
|
5337
|
+
_offeredTotal = 0;
|
|
5338
|
+
_droppedTotal = 0;
|
|
5339
|
+
|
|
5340
|
+
constructor(capacity) {
|
|
5341
|
+
if (!Number.isInteger(capacity) || capacity < 1) {
|
|
5342
|
+
throw new RangeError(
|
|
5343
|
+
`BoundedEmitBuffer capacity must be a positive integer, got ${String(capacity)}`
|
|
5344
|
+
);
|
|
5345
|
+
}
|
|
5346
|
+
this.capacity = capacity;
|
|
5347
|
+
}
|
|
5348
|
+
|
|
5349
|
+
offer(item) {
|
|
5350
|
+
this._offeredTotal += 1;
|
|
5351
|
+
if (this.items.length >= this.capacity) {
|
|
5352
|
+
this._droppedTotal += 1;
|
|
5353
|
+
return false;
|
|
5354
|
+
}
|
|
5355
|
+
this.items.push(item);
|
|
5356
|
+
return true;
|
|
5357
|
+
}
|
|
5358
|
+
|
|
5359
|
+
drain() {
|
|
5360
|
+
if (this.items.length === 0) return [];
|
|
5361
|
+
const out = this.items;
|
|
5362
|
+
this.items = [];
|
|
5363
|
+
return out;
|
|
5364
|
+
}
|
|
5365
|
+
|
|
5366
|
+
get size() {
|
|
5367
|
+
return this.items.length;
|
|
5368
|
+
}
|
|
5369
|
+
|
|
5370
|
+
get maxSize() {
|
|
5371
|
+
return this.capacity;
|
|
5372
|
+
}
|
|
5373
|
+
|
|
5374
|
+
get offeredTotal() {
|
|
5375
|
+
return this._offeredTotal;
|
|
5376
|
+
}
|
|
5377
|
+
|
|
5378
|
+
get droppedTotal() {
|
|
5379
|
+
return this._droppedTotal;
|
|
5380
|
+
}
|
|
5381
|
+
};
|
|
5382
|
+
|
|
5383
|
+
var CompletenessAccounting = class {
|
|
5384
|
+
constructor(lensVersion, config, hooks = {}) {
|
|
5385
|
+
this.lensVersion = lensVersion;
|
|
5386
|
+
this.config = config;
|
|
5387
|
+
this.hooks = hooks;
|
|
5388
|
+
}
|
|
5389
|
+
lensVersion;
|
|
5390
|
+
config;
|
|
5391
|
+
hooks;
|
|
5392
|
+
windowStartMs = null;
|
|
5393
|
+
offered = 0;
|
|
5394
|
+
dropped = 0;
|
|
5395
|
+
delivered = 0;
|
|
5396
|
+
failed = 0;
|
|
5397
|
+
|
|
5398
|
+
channels = new Map();
|
|
5399
|
+
|
|
5400
|
+
sustainedSinceMs = null;
|
|
5401
|
+
|
|
5402
|
+
alerted = false;
|
|
5403
|
+
|
|
5404
|
+
recordOffer(nowMs, accepted) {
|
|
5405
|
+
this.openWindowIfNeeded(nowMs);
|
|
5406
|
+
this.offered += 1;
|
|
5407
|
+
if (!accepted) this.dropped += 1;
|
|
5408
|
+
}
|
|
5409
|
+
|
|
5410
|
+
recordFlush(nowMs, channel, delivered, failed) {
|
|
5411
|
+
this.openWindowIfNeeded(nowMs);
|
|
5412
|
+
this.delivered += delivered;
|
|
5413
|
+
this.failed += failed;
|
|
5414
|
+
const entry = this.channels.get(channel) ?? { attempted: 0, delivered: 0, failed: 0 };
|
|
5415
|
+
entry.attempted += delivered + failed;
|
|
5416
|
+
entry.delivered += delivered;
|
|
5417
|
+
entry.failed += failed;
|
|
5418
|
+
this.channels.set(channel, entry);
|
|
5419
|
+
}
|
|
5420
|
+
|
|
5421
|
+
maybeRollover(nowMs) {
|
|
5422
|
+
if (this.windowStartMs === null) return;
|
|
5423
|
+
if (nowMs - this.windowStartMs < this.config.windowMs) return;
|
|
5424
|
+
this.finalize(this.windowStartMs + this.config.windowMs);
|
|
5425
|
+
}
|
|
5426
|
+
|
|
5427
|
+
snapshot(nowMs) {
|
|
5428
|
+
if (this.windowStartMs === null) return null;
|
|
5429
|
+
return this.buildWindow(this.windowStartMs, nowMs);
|
|
5430
|
+
}
|
|
5431
|
+
|
|
5432
|
+
flushOpenWindow(nowMs) {
|
|
5433
|
+
if (this.windowStartMs === null) return;
|
|
5434
|
+
this.finalize(Math.max(nowMs, this.windowStartMs));
|
|
5435
|
+
}
|
|
5436
|
+
openWindowIfNeeded(nowMs) {
|
|
5437
|
+
this.windowStartMs ??= nowMs;
|
|
5438
|
+
}
|
|
5439
|
+
finalize(windowEndMs) {
|
|
5440
|
+
const start = this.windowStartMs;
|
|
5441
|
+
if (start === null) return;
|
|
5442
|
+
const window = this.buildWindow(start, windowEndMs);
|
|
5443
|
+
this.windowStartMs = null;
|
|
5444
|
+
this.offered = 0;
|
|
5445
|
+
this.dropped = 0;
|
|
5446
|
+
this.delivered = 0;
|
|
5447
|
+
this.failed = 0;
|
|
5448
|
+
this.channels.clear();
|
|
5449
|
+
this.hooks.onWindow?.(window);
|
|
5450
|
+
this.evaluateSustainedLoad(window);
|
|
5451
|
+
}
|
|
5452
|
+
buildWindow(startMs, endMs) {
|
|
5453
|
+
const completenessLowerBound = this.offered === 0 ? 1 : (this.offered - this.dropped) / this.offered;
|
|
5454
|
+
const channels = {};
|
|
5455
|
+
for (const [channel, entry] of this.channels) {
|
|
5456
|
+
channels[channel] = { ...entry };
|
|
5457
|
+
}
|
|
5458
|
+
return {
|
|
5459
|
+
lensVersion: this.lensVersion,
|
|
5460
|
+
windowStartMs: startMs,
|
|
5461
|
+
windowEndMs: endMs,
|
|
5462
|
+
offered: this.offered,
|
|
5463
|
+
dropped: this.dropped,
|
|
5464
|
+
delivered: this.delivered,
|
|
5465
|
+
failed: this.failed,
|
|
5466
|
+
channels,
|
|
5467
|
+
completenessLowerBound,
|
|
5468
|
+
biasFlag: this.dropped > 0
|
|
5469
|
+
};
|
|
5470
|
+
}
|
|
5471
|
+
evaluateSustainedLoad(window) {
|
|
5472
|
+
const rate = window.offered === 0 ? 0 : window.dropped / window.offered;
|
|
5473
|
+
if (rate >= this.config.dropRateThreshold && window.dropped > 0) {
|
|
5474
|
+
this.sustainedSinceMs ??= window.windowStartMs;
|
|
5475
|
+
const sustainedForMs = window.windowEndMs - this.sustainedSinceMs;
|
|
5476
|
+
if (sustainedForMs >= this.config.sustainedForMs && !this.alerted) {
|
|
5477
|
+
this.alerted = true;
|
|
5478
|
+
this.hooks.onExtremeSustainedLoad?.({
|
|
5479
|
+
lensVersion: this.lensVersion,
|
|
5480
|
+
sinceMs: this.sustainedSinceMs,
|
|
5481
|
+
firedAtMs: window.windowEndMs,
|
|
5482
|
+
sustainedForMs,
|
|
5483
|
+
dropRate: rate,
|
|
5484
|
+
dropRateThreshold: this.config.dropRateThreshold
|
|
5485
|
+
});
|
|
5486
|
+
}
|
|
5487
|
+
} else {
|
|
5488
|
+
this.sustainedSinceMs = null;
|
|
5489
|
+
this.alerted = false;
|
|
5490
|
+
}
|
|
5491
|
+
}
|
|
5492
|
+
};
|
|
5493
|
+
|
|
5494
|
+
var DEFAULT_BUFFER_SIZE = 2048;
|
|
5495
|
+
var DEFAULT_FLUSH_INTERVAL_MS = 1e3;
|
|
5496
|
+
var DEFAULT_WINDOW_MS = 1e4;
|
|
5497
|
+
var DEFAULT_DROP_RATE_THRESHOLD = 0.01;
|
|
5498
|
+
var DEFAULT_SUSTAINED_FOR_MS = 6e4;
|
|
5499
|
+
var DEFAULT_SENTINEL_INTERVAL_MS = 3e4;
|
|
5500
|
+
var streamIdFallbackCounter = 0;
|
|
5501
|
+
function generateStreamId(nowMs) {
|
|
5502
|
+
const cryptoObj = globalThis.crypto;
|
|
5503
|
+
if (typeof cryptoObj?.randomUUID === "function") return cryptoObj.randomUUID();
|
|
5504
|
+
streamIdFallbackCounter += 1;
|
|
5505
|
+
return `stream-${String(nowMs)}-${String(streamIdFallbackCounter)}`;
|
|
5506
|
+
}
|
|
5507
|
+
function defaultScheduleInterval(fn, ms) {
|
|
5508
|
+
const handle = setInterval(fn, ms);
|
|
5509
|
+
handle.unref?.();
|
|
5510
|
+
return () => {
|
|
5511
|
+
clearInterval(handle);
|
|
5512
|
+
};
|
|
5513
|
+
}
|
|
5514
|
+
var EvaluationEventEmitter = class {
|
|
5515
|
+
buffer;
|
|
5516
|
+
flushTargets;
|
|
5517
|
+
|
|
5518
|
+
sentinelTargets;
|
|
5519
|
+
accounting;
|
|
5520
|
+
now;
|
|
5521
|
+
onFlushError;
|
|
5522
|
+
stopInterval;
|
|
5523
|
+
stopSentinelInterval;
|
|
5524
|
+
|
|
5525
|
+
streamId;
|
|
5526
|
+
nextSeq = 0;
|
|
5527
|
+
|
|
5528
|
+
lastSeq = -1;
|
|
5529
|
+
|
|
5530
|
+
inFlight = null;
|
|
5531
|
+
stopped = false;
|
|
5532
|
+
constructor(opts) {
|
|
5533
|
+
this.buffer = new BoundedEmitBuffer(opts.bufferSize ?? DEFAULT_BUFFER_SIZE);
|
|
5534
|
+
if (opts.flushTargets.length === 0) {
|
|
5535
|
+
throw new Error("EvaluationEventEmitter requires at least one flush target");
|
|
5536
|
+
}
|
|
5537
|
+
this.flushTargets = [...opts.flushTargets];
|
|
5538
|
+
this.sentinelTargets = this.flushTargets.filter((t) => typeof t.emitSentinel === "function");
|
|
5539
|
+
this.now = opts.now ?? Date.now;
|
|
5540
|
+
this.streamId = opts.streamId ?? generateStreamId(this.now());
|
|
5541
|
+
this.onFlushError = opts.onFlushError ?? ((error) => {
|
|
5542
|
+
console.warn("[holonograph] emit flush error:", error);
|
|
5543
|
+
});
|
|
5544
|
+
const config = {
|
|
5545
|
+
windowMs: opts.windowMs ?? DEFAULT_WINDOW_MS,
|
|
5546
|
+
dropRateThreshold: opts.extremeSustainedLoad?.dropRateThreshold ?? DEFAULT_DROP_RATE_THRESHOLD,
|
|
5547
|
+
sustainedForMs: opts.extremeSustainedLoad?.sustainedForMs ?? DEFAULT_SUSTAINED_FOR_MS
|
|
5548
|
+
};
|
|
5549
|
+
this.accounting = new CompletenessAccounting(opts.lensVersion, config, {
|
|
5550
|
+
...opts.onWindow !== void 0 ? { onWindow: opts.onWindow } : {},
|
|
5551
|
+
...opts.onExtremeSustainedLoad !== void 0 ? { onExtremeSustainedLoad: opts.onExtremeSustainedLoad } : {}
|
|
5552
|
+
});
|
|
5553
|
+
const schedule = opts.scheduleInterval ?? defaultScheduleInterval;
|
|
5554
|
+
this.stopInterval = schedule(() => {
|
|
5555
|
+
this.tick();
|
|
5556
|
+
}, opts.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS);
|
|
5557
|
+
this.stopSentinelInterval = schedule(() => {
|
|
5558
|
+
this.sentinelTick();
|
|
5559
|
+
}, opts.sentinelIntervalMs ?? DEFAULT_SENTINEL_INTERVAL_MS);
|
|
5560
|
+
}
|
|
5561
|
+
|
|
5562
|
+
enqueue(event) {
|
|
5563
|
+
const nowMs = this.now();
|
|
5564
|
+
const seq = this.nextSeq;
|
|
5565
|
+
this.nextSeq += 1;
|
|
5566
|
+
this.lastSeq = seq;
|
|
5567
|
+
const accepted = this.buffer.offer({ event, seq, streamId: this.streamId });
|
|
5568
|
+
this.accounting.recordOffer(nowMs, accepted);
|
|
5569
|
+
this.accounting.maybeRollover(nowMs);
|
|
5570
|
+
return event.eventId;
|
|
5571
|
+
}
|
|
5572
|
+
|
|
5573
|
+
tick() {
|
|
5574
|
+
void this.flushNow();
|
|
5575
|
+
this.accounting.maybeRollover(this.now());
|
|
5576
|
+
}
|
|
5577
|
+
|
|
5578
|
+
sentinelTick() {
|
|
5579
|
+
if (this.lastSeq < 0) return;
|
|
5580
|
+
void this.emitSentinelNow(false);
|
|
5581
|
+
}
|
|
5582
|
+
|
|
5583
|
+
async emitSentinelNow(final) {
|
|
5584
|
+
if (this.sentinelTargets.length === 0) return;
|
|
5585
|
+
const sentinel = { streamId: this.streamId, seq: this.lastSeq, final };
|
|
5586
|
+
await Promise.all(
|
|
5587
|
+
this.sentinelTargets.map(
|
|
5588
|
+
(t) => (t.emitSentinel?.(sentinel) ?? Promise.resolve()).catch((error) => {
|
|
5589
|
+
this.onFlushError(error);
|
|
5590
|
+
})
|
|
5591
|
+
)
|
|
5592
|
+
);
|
|
5593
|
+
}
|
|
5594
|
+
|
|
5595
|
+
flushNow() {
|
|
5596
|
+
if (this.inFlight) return this.inFlight;
|
|
5597
|
+
const batch = this.buffer.drain();
|
|
5598
|
+
if (batch.length === 0) return Promise.resolve();
|
|
5599
|
+
const flush = this.doFlush(batch).finally(() => {
|
|
5600
|
+
this.inFlight = null;
|
|
5601
|
+
});
|
|
5602
|
+
this.inFlight = flush;
|
|
5603
|
+
return flush;
|
|
5604
|
+
}
|
|
5605
|
+
async doFlush(batch) {
|
|
5606
|
+
await Promise.all(this.flushTargets.map((target) => this.flushToTarget(target, batch)));
|
|
5607
|
+
}
|
|
5608
|
+
async flushToTarget(target, batch) {
|
|
5609
|
+
const channel = target.channel;
|
|
5610
|
+
try {
|
|
5611
|
+
const result = await target.flushBatch(batch);
|
|
5612
|
+
this.accounting.recordFlush(this.now(), channel, result.delivered, result.failed);
|
|
5613
|
+
for (const error of result.errors) this.onFlushError(error);
|
|
5614
|
+
} catch (error) {
|
|
5615
|
+
this.accounting.recordFlush(this.now(), channel, 0, batch.length);
|
|
5616
|
+
this.onFlushError(error);
|
|
5617
|
+
}
|
|
5618
|
+
}
|
|
5619
|
+
|
|
5620
|
+
snapshotWindow() {
|
|
5621
|
+
return this.accounting.snapshot(this.now());
|
|
5622
|
+
}
|
|
5623
|
+
|
|
5624
|
+
async shutdown() {
|
|
5625
|
+
if (this.stopped) return;
|
|
5626
|
+
this.stopped = true;
|
|
5627
|
+
this.stopInterval();
|
|
5628
|
+
this.stopSentinelInterval();
|
|
5629
|
+
while (this.buffer.size > 0 || this.inFlight) {
|
|
5630
|
+
await this.flushNow();
|
|
5631
|
+
}
|
|
5632
|
+
if (this.lastSeq >= 0) await this.emitSentinelNow(true);
|
|
5633
|
+
await Promise.all(this.flushTargets.map((t) => t.shutdown?.() ?? Promise.resolve()));
|
|
5634
|
+
this.accounting.flushOpenWindow(this.now());
|
|
5635
|
+
}
|
|
5636
|
+
};
|
|
5637
|
+
|
|
5638
|
+
var HttpEventFlushTarget = class {
|
|
5639
|
+
|
|
5640
|
+
constructor(postEvent) {
|
|
5641
|
+
this.postEvent = postEvent;
|
|
5642
|
+
}
|
|
5643
|
+
postEvent;
|
|
5644
|
+
|
|
5645
|
+
channel = "http";
|
|
5646
|
+
async flushBatch(items) {
|
|
5647
|
+
let delivered = 0;
|
|
5648
|
+
let failed = 0;
|
|
5649
|
+
const errors = [];
|
|
5650
|
+
for (const item of items) {
|
|
5651
|
+
try {
|
|
5652
|
+
await this.postEvent(item.event);
|
|
5653
|
+
delivered += 1;
|
|
5654
|
+
} catch (error) {
|
|
5655
|
+
failed += 1;
|
|
5656
|
+
errors.push(error);
|
|
5657
|
+
}
|
|
5658
|
+
}
|
|
5659
|
+
return { delivered, failed, errors };
|
|
5660
|
+
}
|
|
5661
|
+
};
|
|
5662
|
+
|
|
5663
|
+
var EVALUATION_SPAN_NAME = "holonograph.evaluation";
|
|
5664
|
+
var DIMENSION_EVENT_NAME = "holonograph.dimension";
|
|
5665
|
+
var SENTINEL_SPAN_NAME = "holonograph.session.sentinel";
|
|
5666
|
+
var SPAN_ATTR = {
|
|
5667
|
+
eventId: "holonograph.event.id",
|
|
5668
|
+
correlationId: "holonograph.correlation_id",
|
|
5669
|
+
surfaceId: "holonograph.surface.id",
|
|
5670
|
+
fixtureId: "holonograph.surface.fixture_id",
|
|
5671
|
+
passed: "holonograph.surface.passed",
|
|
5672
|
+
cohortTags: "holonograph.surface.cohort_tags",
|
|
5673
|
+
lensVersion: "holonograph.lens.version",
|
|
5674
|
+
lightSourceId: "holonograph.light_source.id",
|
|
5675
|
+
runMode: "holonograph.run_mode",
|
|
5676
|
+
provenance: "holonograph.provenance",
|
|
5677
|
+
latencyMs: "holonograph.light.latency_ms",
|
|
5678
|
+
tokensInput: "holonograph.light.tokens.input",
|
|
5679
|
+
tokensOutput: "holonograph.light.tokens.output",
|
|
5680
|
+
ok: "holonograph.light.ok",
|
|
5681
|
+
|
|
5682
|
+
rawResponseLocation: "holonograph.raw_response.location",
|
|
5683
|
+
|
|
5684
|
+
substratePrefix: "holonograph.substrate.",
|
|
5685
|
+
dimensionId: "holonograph.dimension.id",
|
|
5686
|
+
dimensionPassed: "holonograph.dimension.passed",
|
|
5687
|
+
dimensionScore: "holonograph.dimension.score",
|
|
5688
|
+
|
|
5689
|
+
emissionSeq: "holonograph.emission.seq",
|
|
5690
|
+
emissionStream: "holonograph.emission.stream",
|
|
5691
|
+
|
|
5692
|
+
emissionFinal: "holonograph.emission.final"
|
|
5693
|
+
};
|
|
5694
|
+
function buildEvaluationSpanData(event, emission, options) {
|
|
5695
|
+
const light = event.light;
|
|
5696
|
+
const surface = event.surface;
|
|
5697
|
+
const substrate = event.substrate;
|
|
5698
|
+
const startTimeMs = Date.parse(event.occurredAt);
|
|
5699
|
+
const latencyMs = typeof light?.latencyMs === "number" ? light.latencyMs : 0;
|
|
5700
|
+
const endTimeMs = startTimeMs + latencyMs;
|
|
5701
|
+
const isError = light?.error !== void 0;
|
|
5702
|
+
const attributes = {
|
|
5703
|
+
[SPAN_ATTR.eventId]: event.eventId,
|
|
5704
|
+
[SPAN_ATTR.correlationId]: event.correlationId,
|
|
5705
|
+
[SPAN_ATTR.surfaceId]: event.surfaceId,
|
|
5706
|
+
[SPAN_ATTR.lensVersion]: event.lensVersion,
|
|
5707
|
+
[SPAN_ATTR.ok]: !isError,
|
|
5708
|
+
|
|
5709
|
+
[SPAN_ATTR.rawResponseLocation]: options?.rawResponseLocation ?? "store"
|
|
5710
|
+
};
|
|
5711
|
+
if (surface !== void 0) {
|
|
5712
|
+
attributes[SPAN_ATTR.fixtureId] = surface.fixtureId;
|
|
5713
|
+
attributes[SPAN_ATTR.passed] = surface.passed;
|
|
5714
|
+
attributes[SPAN_ATTR.cohortTags] = [...surface.cohortTags];
|
|
5715
|
+
}
|
|
5716
|
+
if (substrate !== void 0) {
|
|
5717
|
+
attributes[SPAN_ATTR.lightSourceId] = substrate.lightSourceIdentifier;
|
|
5718
|
+
attributes[SPAN_ATTR.runMode] = substrate.runMode;
|
|
5719
|
+
attributes[SPAN_ATTR.provenance] = substrate.provenance;
|
|
5720
|
+
for (const [key, value] of Object.entries(substrate.columns)) {
|
|
5721
|
+
attributes[`${SPAN_ATTR.substratePrefix}${key}`] = value;
|
|
5722
|
+
}
|
|
5723
|
+
}
|
|
5724
|
+
if (typeof light?.latencyMs === "number") attributes[SPAN_ATTR.latencyMs] = light.latencyMs;
|
|
5725
|
+
if (light?.tokens?.input !== void 0) attributes[SPAN_ATTR.tokensInput] = light.tokens.input;
|
|
5726
|
+
if (light?.tokens?.output !== void 0) attributes[SPAN_ATTR.tokensOutput] = light.tokens.output;
|
|
5727
|
+
if (emission !== void 0) {
|
|
5728
|
+
attributes[SPAN_ATTR.emissionSeq] = emission.seq;
|
|
5729
|
+
attributes[SPAN_ATTR.emissionStream] = emission.streamId;
|
|
5730
|
+
}
|
|
5731
|
+
const dimensionEvents = (surface?.dimensions ?? []).map((d) => {
|
|
5732
|
+
const attrs = {
|
|
5733
|
+
[SPAN_ATTR.dimensionId]: d.dimensionId,
|
|
5734
|
+
[SPAN_ATTR.dimensionPassed]: d.passed
|
|
5735
|
+
};
|
|
5736
|
+
if (d.score !== void 0) attrs[SPAN_ATTR.dimensionScore] = d.score;
|
|
5737
|
+
return { name: DIMENSION_EVENT_NAME, attributes: attrs };
|
|
5738
|
+
});
|
|
5739
|
+
return {
|
|
5740
|
+
name: EVALUATION_SPAN_NAME,
|
|
5741
|
+
startTimeMs,
|
|
5742
|
+
endTimeMs,
|
|
5743
|
+
attributes,
|
|
5744
|
+
dimensionEvents,
|
|
5745
|
+
isError,
|
|
5746
|
+
errorMessage: light?.error?.message
|
|
5747
|
+
};
|
|
5748
|
+
}
|
|
5749
|
+
function writeEvaluationSpan(tracer, event, otel, emission, options) {
|
|
5750
|
+
const data = buildEvaluationSpanData(event, emission, options);
|
|
5751
|
+
const span = tracer.startSpan(data.name, {
|
|
5752
|
+
startTime: data.startTimeMs,
|
|
5753
|
+
kind: otel.SpanKindClient,
|
|
5754
|
+
attributes: data.attributes
|
|
5755
|
+
});
|
|
5756
|
+
for (const ev of data.dimensionEvents) span.addEvent(ev.name, ev.attributes);
|
|
5757
|
+
if (data.isError) {
|
|
5758
|
+
span.setStatus(
|
|
5759
|
+
data.errorMessage !== void 0 ? { code: otel.statusError, message: data.errorMessage } : { code: otel.statusError }
|
|
5760
|
+
);
|
|
5761
|
+
} else {
|
|
5762
|
+
span.setStatus({ code: otel.statusOk });
|
|
5763
|
+
}
|
|
5764
|
+
span.end(data.endTimeMs);
|
|
5765
|
+
}
|
|
5766
|
+
function writeSentinelSpan(tracer, sentinel, otel) {
|
|
5767
|
+
const span = tracer.startSpan(SENTINEL_SPAN_NAME, {
|
|
5768
|
+
kind: otel.SpanKindClient,
|
|
5769
|
+
attributes: {
|
|
5770
|
+
[SPAN_ATTR.emissionStream]: sentinel.streamId,
|
|
5771
|
+
[SPAN_ATTR.emissionSeq]: sentinel.seq,
|
|
5772
|
+
[SPAN_ATTR.emissionFinal]: sentinel.final
|
|
5773
|
+
}
|
|
5774
|
+
});
|
|
5775
|
+
span.setStatus({ code: otel.statusOk });
|
|
5776
|
+
span.end();
|
|
5777
|
+
}
|
|
5778
|
+
|
|
5779
|
+
function reconcileBatchDelivery(batchSize, delivered, exportFailed) {
|
|
5780
|
+
const shed = Math.max(0, batchSize - delivered - exportFailed);
|
|
5781
|
+
return { delivered, failed: exportFailed + shed };
|
|
5782
|
+
}
|
|
5783
|
+
var CountingExporter = class {
|
|
5784
|
+
constructor(inner, tally, successCode) {
|
|
5785
|
+
this.inner = inner;
|
|
5786
|
+
this.tally = tally;
|
|
5787
|
+
this.successCode = successCode;
|
|
5788
|
+
}
|
|
5789
|
+
inner;
|
|
5790
|
+
tally;
|
|
5791
|
+
successCode;
|
|
5792
|
+
export(spans, resultCallback) {
|
|
5793
|
+
this.inner.export(spans, (result) => {
|
|
5794
|
+
if (result.code === this.successCode) {
|
|
5795
|
+
this.tally.delivered += spans.length;
|
|
5796
|
+
} else {
|
|
5797
|
+
this.tally.failed += spans.length;
|
|
5798
|
+
if (result.error) this.tally.errors.push(result.error);
|
|
5799
|
+
}
|
|
5800
|
+
resultCallback(result);
|
|
5801
|
+
});
|
|
5802
|
+
}
|
|
5803
|
+
shutdown() {
|
|
5804
|
+
return this.inner.shutdown();
|
|
5805
|
+
}
|
|
5806
|
+
forceFlush() {
|
|
5807
|
+
return this.inner.forceFlush?.() ?? Promise.resolve();
|
|
5808
|
+
}
|
|
5809
|
+
};
|
|
5810
|
+
var OtlpEventFlushTarget = class {
|
|
5811
|
+
channel = "otlp";
|
|
5812
|
+
options;
|
|
5813
|
+
tally = { delivered: 0, failed: 0, errors: [] };
|
|
5814
|
+
provider;
|
|
5815
|
+
tracer;
|
|
5816
|
+
otel;
|
|
5817
|
+
initPromise;
|
|
5818
|
+
|
|
5819
|
+
opLock = Promise.resolve();
|
|
5820
|
+
constructor(options) {
|
|
5821
|
+
this.options = options;
|
|
5822
|
+
}
|
|
5823
|
+
|
|
5824
|
+
serialize(fn) {
|
|
5825
|
+
const run = this.opLock.then(fn, fn);
|
|
5826
|
+
this.opLock = run.then(
|
|
5827
|
+
() => void 0,
|
|
5828
|
+
() => void 0
|
|
5829
|
+
);
|
|
5830
|
+
return run;
|
|
5831
|
+
}
|
|
5832
|
+
flushBatch(items) {
|
|
5833
|
+
return this.serialize(() => this.doFlushBatch(items));
|
|
5834
|
+
}
|
|
5835
|
+
async doFlushBatch(items) {
|
|
5836
|
+
await this.ensureInit();
|
|
5837
|
+
const tracer = this.tracer;
|
|
5838
|
+
const otel = this.otel;
|
|
5839
|
+
const provider = this.provider;
|
|
5840
|
+
if (!tracer || !otel || !provider) {
|
|
5841
|
+
return {
|
|
5842
|
+
delivered: 0,
|
|
5843
|
+
failed: items.length,
|
|
5844
|
+
errors: [new Error("OTLP target not initialized")]
|
|
5845
|
+
};
|
|
5846
|
+
}
|
|
5847
|
+
const beforeDelivered = this.tally.delivered;
|
|
5848
|
+
const beforeFailed = this.tally.failed;
|
|
5849
|
+
const beforeErrors = this.tally.errors.length;
|
|
5850
|
+
const spanOptions = {
|
|
5851
|
+
rawResponseLocation: this.options.rawResponseLocation ?? "store"
|
|
5852
|
+
};
|
|
5853
|
+
for (const item of items) {
|
|
5854
|
+
writeEvaluationSpan(
|
|
5855
|
+
tracer,
|
|
5856
|
+
item.event,
|
|
5857
|
+
otel,
|
|
5858
|
+
{ seq: item.seq, streamId: item.streamId },
|
|
5859
|
+
spanOptions
|
|
5860
|
+
);
|
|
5861
|
+
}
|
|
5862
|
+
await provider.forceFlush();
|
|
5863
|
+
const delivered = this.tally.delivered - beforeDelivered;
|
|
5864
|
+
const exportFailed = this.tally.failed - beforeFailed;
|
|
5865
|
+
const reconciled = reconcileBatchDelivery(items.length, delivered, exportFailed);
|
|
5866
|
+
return { ...reconciled, errors: this.tally.errors.slice(beforeErrors) };
|
|
5867
|
+
}
|
|
5868
|
+
|
|
5869
|
+
emitSentinel(sentinel) {
|
|
5870
|
+
return this.serialize(async () => {
|
|
5871
|
+
await this.ensureInit();
|
|
5872
|
+
if (!this.tracer || !this.otel || !this.provider) return;
|
|
5873
|
+
writeSentinelSpan(this.tracer, sentinel, this.otel);
|
|
5874
|
+
await this.provider.forceFlush();
|
|
5875
|
+
});
|
|
5876
|
+
}
|
|
5877
|
+
async shutdown() {
|
|
5878
|
+
if (this.provider) await this.provider.shutdown();
|
|
5879
|
+
}
|
|
5880
|
+
|
|
5881
|
+
ensureInit() {
|
|
5882
|
+
this.initPromise ??= this.doInit();
|
|
5883
|
+
return this.initPromise;
|
|
5884
|
+
}
|
|
5885
|
+
async doInit() {
|
|
5886
|
+
const [api, sdk, resources, core] = await Promise.all([
|
|
5887
|
+
import('@opentelemetry/api'),
|
|
5888
|
+
import('@opentelemetry/sdk-trace-base'),
|
|
5889
|
+
import('@opentelemetry/resources'),
|
|
5890
|
+
import('@opentelemetry/core')
|
|
5891
|
+
]);
|
|
5892
|
+
let exporter;
|
|
5893
|
+
if (this.options.exporter) {
|
|
5894
|
+
exporter = this.options.exporter;
|
|
5895
|
+
} else {
|
|
5896
|
+
const otlp = await import('@opentelemetry/exporter-trace-otlp-http');
|
|
5897
|
+
const exporterConfig = {};
|
|
5898
|
+
if (this.options.endpoint !== void 0) exporterConfig.url = this.options.endpoint;
|
|
5899
|
+
if (this.options.headers !== void 0) exporterConfig.headers = this.options.headers;
|
|
5900
|
+
exporter = new otlp.OTLPTraceExporter(exporterConfig);
|
|
5901
|
+
}
|
|
5902
|
+
const counting = new CountingExporter(exporter, this.tally, core.ExportResultCode.SUCCESS);
|
|
5903
|
+
const resource = resources.resourceFromAttributes({
|
|
5904
|
+
"service.name": "holonograph-client",
|
|
5905
|
+
"holonograph.lens.version": this.options.lensVersion
|
|
5906
|
+
});
|
|
5907
|
+
this.provider = new sdk.BasicTracerProvider({
|
|
5908
|
+
resource,
|
|
5909
|
+
spanProcessors: [
|
|
5910
|
+
new sdk.BatchSpanProcessor(counting, {
|
|
5911
|
+
maxQueueSize: this.options.maxQueueSize ?? 4096
|
|
5912
|
+
})
|
|
5913
|
+
]
|
|
5914
|
+
});
|
|
5915
|
+
this.tracer = this.provider.getTracer("holonograph-client");
|
|
5916
|
+
this.otel = {
|
|
5917
|
+
SpanKindClient: api.SpanKind.CLIENT,
|
|
5918
|
+
statusOk: api.SpanStatusCode.OK,
|
|
5919
|
+
statusError: api.SpanStatusCode.ERROR
|
|
5920
|
+
};
|
|
5921
|
+
}
|
|
5922
|
+
};
|
|
5923
|
+
|
|
5313
5924
|
var HolonographHttpError = class extends Error {
|
|
5314
5925
|
constructor(status, code, message, details) {
|
|
5315
5926
|
super(message);
|
|
@@ -5327,11 +5938,46 @@ var HttpTransport = class {
|
|
|
5327
5938
|
token;
|
|
5328
5939
|
fetchImpl;
|
|
5329
5940
|
runMode;
|
|
5941
|
+
|
|
5942
|
+
emitter;
|
|
5330
5943
|
constructor(opts) {
|
|
5331
5944
|
this.endpoint = opts.endpoint.replace(/\/$/, "");
|
|
5332
5945
|
this.token = opts.token;
|
|
5333
5946
|
this.fetchImpl = opts.fetch ?? globalThis.fetch.bind(globalThis);
|
|
5334
5947
|
this.runMode = opts.runMode;
|
|
5948
|
+
const e = opts.emit;
|
|
5949
|
+
const mode = e?.mode;
|
|
5950
|
+
if (e !== void 0 && (mode === "buffered" || mode === "otlp" || mode === "dual")) {
|
|
5951
|
+
const lensVersion = opts.lensVersion ?? "unknown";
|
|
5952
|
+
const flushTargets = [];
|
|
5953
|
+
if (mode === "buffered" || mode === "dual") {
|
|
5954
|
+
flushTargets.push(new HttpEventFlushTarget((event) => this.postEvent(event)));
|
|
5955
|
+
}
|
|
5956
|
+
if (mode === "otlp" || mode === "dual") {
|
|
5957
|
+
const otlpOpts = { lensVersion };
|
|
5958
|
+
if (e.otlp?.endpoint !== void 0) otlpOpts.endpoint = e.otlp.endpoint;
|
|
5959
|
+
if (e.otlp?.headers !== void 0) otlpOpts.headers = e.otlp.headers;
|
|
5960
|
+
otlpOpts.maxQueueSize = e.otlp?.maxQueueSize ?? (e.bufferSize ?? 2048) * 2;
|
|
5961
|
+
otlpOpts.rawResponseLocation = mode === "dual" ? "http-channel" : "store";
|
|
5962
|
+
flushTargets.push(new OtlpEventFlushTarget(otlpOpts));
|
|
5963
|
+
}
|
|
5964
|
+
const emitterOpts = { flushTargets, lensVersion };
|
|
5965
|
+
if (e.bufferSize !== void 0) emitterOpts.bufferSize = e.bufferSize;
|
|
5966
|
+
if (e.flushIntervalMs !== void 0) emitterOpts.flushIntervalMs = e.flushIntervalMs;
|
|
5967
|
+
if (e.sentinelIntervalMs !== void 0) emitterOpts.sentinelIntervalMs = e.sentinelIntervalMs;
|
|
5968
|
+
if (e.windowMs !== void 0) emitterOpts.windowMs = e.windowMs;
|
|
5969
|
+
if (e.extremeSustainedLoad !== void 0) {
|
|
5970
|
+
emitterOpts.extremeSustainedLoad = e.extremeSustainedLoad;
|
|
5971
|
+
}
|
|
5972
|
+
if (e.onWindow !== void 0) emitterOpts.onWindow = e.onWindow;
|
|
5973
|
+
if (e.onExtremeSustainedLoad !== void 0) {
|
|
5974
|
+
emitterOpts.onExtremeSustainedLoad = e.onExtremeSustainedLoad;
|
|
5975
|
+
}
|
|
5976
|
+
if (e.onFlushError !== void 0) emitterOpts.onFlushError = e.onFlushError;
|
|
5977
|
+
this.emitter = new EvaluationEventEmitter(emitterOpts);
|
|
5978
|
+
} else {
|
|
5979
|
+
this.emitter = void 0;
|
|
5980
|
+
}
|
|
5335
5981
|
}
|
|
5336
5982
|
async dispatch(req) {
|
|
5337
5983
|
const wire = await this.post(
|
|
@@ -5366,9 +6012,24 @@ var HttpTransport = class {
|
|
|
5366
6012
|
return result;
|
|
5367
6013
|
}
|
|
5368
6014
|
async appendEvent(event) {
|
|
6015
|
+
if (this.emitter) {
|
|
6016
|
+
return this.emitter.enqueue(event);
|
|
6017
|
+
}
|
|
5369
6018
|
const result = await this.post("/lens/events", event, event.correlationId);
|
|
5370
6019
|
return result.eventId;
|
|
5371
6020
|
}
|
|
6021
|
+
|
|
6022
|
+
async postEvent(event) {
|
|
6023
|
+
await this.post("/lens/events", event, event.correlationId);
|
|
6024
|
+
}
|
|
6025
|
+
|
|
6026
|
+
completenessWindow() {
|
|
6027
|
+
return this.emitter?.snapshotWindow() ?? null;
|
|
6028
|
+
}
|
|
6029
|
+
|
|
6030
|
+
async shutdown() {
|
|
6031
|
+
if (this.emitter) await this.emitter.shutdown();
|
|
6032
|
+
}
|
|
5372
6033
|
async postContract(contract) {
|
|
5373
6034
|
return this.post("/holonograph/contract", contract);
|
|
5374
6035
|
}
|
|
@@ -5494,6 +6155,7 @@ function flattenSystemBlocks(blocks) {
|
|
|
5494
6155
|
var HolonographClient = class {
|
|
5495
6156
|
transport;
|
|
5496
6157
|
inProcessTransport;
|
|
6158
|
+
httpTransport;
|
|
5497
6159
|
lensVersion;
|
|
5498
6160
|
substrate;
|
|
5499
6161
|
|
|
@@ -5513,12 +6175,17 @@ var HolonographClient = class {
|
|
|
5513
6175
|
constructor(options) {
|
|
5514
6176
|
if (isHttpOptions(options)) {
|
|
5515
6177
|
const httpOpts = {
|
|
5516
|
-
endpoint: options.endpoint
|
|
6178
|
+
endpoint: options.endpoint,
|
|
6179
|
+
|
|
6180
|
+
lensVersion: options.lensVersion
|
|
5517
6181
|
};
|
|
5518
6182
|
if (options.token !== void 0) httpOpts.token = options.token;
|
|
5519
6183
|
if (options.fetch !== void 0) httpOpts.fetch = options.fetch;
|
|
5520
6184
|
if (options.runMode !== void 0) httpOpts.runMode = options.runMode;
|
|
5521
|
-
|
|
6185
|
+
if (options.emit !== void 0) httpOpts.emit = options.emit;
|
|
6186
|
+
const t = new HttpTransport(httpOpts);
|
|
6187
|
+
this.transport = t;
|
|
6188
|
+
this.httpTransport = t;
|
|
5522
6189
|
this.inProcessTransport = void 0;
|
|
5523
6190
|
} else {
|
|
5524
6191
|
const inProcOpts = {
|
|
@@ -5529,6 +6196,7 @@ var HolonographClient = class {
|
|
|
5529
6196
|
const t = new InProcessTransport(inProcOpts);
|
|
5530
6197
|
this.transport = t;
|
|
5531
6198
|
this.inProcessTransport = t;
|
|
6199
|
+
this.httpTransport = void 0;
|
|
5532
6200
|
}
|
|
5533
6201
|
this.lensVersion = options.lensVersion;
|
|
5534
6202
|
this.substrate = options.substrate;
|
|
@@ -5588,6 +6256,14 @@ var HolonographClient = class {
|
|
|
5588
6256
|
return this.inProcessTransport ? this.inProcessTransport.topology : null;
|
|
5589
6257
|
}
|
|
5590
6258
|
|
|
6259
|
+
completenessWindow() {
|
|
6260
|
+
return this.httpTransport?.completenessWindow() ?? null;
|
|
6261
|
+
}
|
|
6262
|
+
|
|
6263
|
+
async shutdown() {
|
|
6264
|
+
if (this.httpTransport) await this.httpTransport.shutdown();
|
|
6265
|
+
}
|
|
6266
|
+
|
|
5591
6267
|
fetchDeclaredColumns(force = false) {
|
|
5592
6268
|
const getContract = this.transport.getContract?.bind(this.transport);
|
|
5593
6269
|
if (getContract === void 0) return Promise.resolve(null);
|