@elaraai/e3-ui-components 1.0.13 → 1.0.14
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/components/UITaskPreview.d.ts.map +1 -1
- package/dist/experiment/index.d.ts.map +1 -1
- package/dist/index.cjs +685 -143
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +688 -146
- package/dist/index.js.map +1 -1
- package/dist/platform/bind-runtime.d.ts +3 -0
- package/dist/platform/bind-runtime.d.ts.map +1 -1
- package/dist/platform/dataset-hooks.d.ts.map +1 -1
- package/dist/platform/dataset-store.d.ts +24 -1
- package/dist/platform/dataset-store.d.ts.map +1 -1
- package/dist/platform/func-runtime.d.ts +20 -16
- package/dist/platform/func-runtime.d.ts.map +1 -1
- package/dist/platform/index.d.ts +2 -1
- package/dist/platform/index.d.ts.map +1 -1
- package/dist/platform/record-runtime.d.ts +127 -0
- package/dist/platform/record-runtime.d.ts.map +1 -0
- package/dist/platform/staged-store.d.ts +17 -1
- package/dist/platform/staged-store.d.ts.map +1 -1
- package/dist/platform/tracked-channel.d.ts +71 -0
- package/dist/platform/tracked-channel.d.ts.map +1 -0
- package/package.json +14 -14
package/dist/index.cjs
CHANGED
|
@@ -2106,9 +2106,6 @@ function datasetCacheKey(workspace, path2) {
|
|
|
2106
2106
|
const pathStr = datasetPathToString(path2);
|
|
2107
2107
|
return pathStr ? `${workspace}.${pathStr}` : workspace;
|
|
2108
2108
|
}
|
|
2109
|
-
function toTreePath(path2) {
|
|
2110
|
-
return path2;
|
|
2111
|
-
}
|
|
2112
2109
|
class ReactiveDatasetCache {
|
|
2113
2110
|
constructor(config2, api3, clock2 = realClock) {
|
|
2114
2111
|
__publicField(this, "destroyed", false);
|
|
@@ -2230,7 +2227,7 @@ class ReactiveDatasetCache {
|
|
|
2230
2227
|
const prevTail = this.writeChains.get(key) ?? Promise.resolve();
|
|
2231
2228
|
const run = prevTail.then(async () => {
|
|
2232
2229
|
try {
|
|
2233
|
-
await this.api.set(workspace,
|
|
2230
|
+
await this.api.set(workspace, path2, value);
|
|
2234
2231
|
if (this.destroyed) return;
|
|
2235
2232
|
this.writeBaselines.set(key, {
|
|
2236
2233
|
value,
|
|
@@ -2285,6 +2282,14 @@ class ReactiveDatasetCache {
|
|
|
2285
2282
|
if (this.destroyed) return;
|
|
2286
2283
|
await this.api.launchDataflow(workspace);
|
|
2287
2284
|
}
|
|
2285
|
+
/**
|
|
2286
|
+
* Launch a workspace dataflow run without writing first. The standalone
|
|
2287
|
+
* half of {@link writeAndStart}; see the interface doc for semantics.
|
|
2288
|
+
*/
|
|
2289
|
+
async launchDataflow(workspace) {
|
|
2290
|
+
if (this.destroyed) return;
|
|
2291
|
+
await this.api.launchDataflow(workspace);
|
|
2292
|
+
}
|
|
2288
2293
|
/**
|
|
2289
2294
|
* Preload a dataset into cache. Concurrent preloads of the same key
|
|
2290
2295
|
* share one fetch (query-core dedup); a write racing the fetch cancels
|
|
@@ -2300,7 +2305,7 @@ class ReactiveDatasetCache {
|
|
|
2300
2305
|
await this.client.fetchQuery({
|
|
2301
2306
|
queryKey,
|
|
2302
2307
|
queryFn: async () => {
|
|
2303
|
-
const result = await this.
|
|
2308
|
+
const result = await this.api.get(workspace, path2);
|
|
2304
2309
|
fetchedHash = result.hash;
|
|
2305
2310
|
return result.data;
|
|
2306
2311
|
}
|
|
@@ -2316,14 +2321,11 @@ class ReactiveDatasetCache {
|
|
|
2316
2321
|
this.knownHashes.set(key, fetchedHash);
|
|
2317
2322
|
this.notifyChange(key);
|
|
2318
2323
|
}
|
|
2319
|
-
fetchDataset(workspace, path2) {
|
|
2320
|
-
return this.api.get(workspace, toTreePath(path2));
|
|
2321
|
-
}
|
|
2322
2324
|
/**
|
|
2323
2325
|
* List fields at a path. Empty path lists workspace root.
|
|
2324
2326
|
*/
|
|
2325
2327
|
list(workspace, path2) {
|
|
2326
|
-
return path2.length === 0 ? this.api.listRoot(workspace) : this.api.listAt(workspace,
|
|
2328
|
+
return path2.length === 0 ? this.api.listRoot(workspace) : this.api.listAt(workspace, path2);
|
|
2327
2329
|
}
|
|
2328
2330
|
/**
|
|
2329
2331
|
* Set refetch interval for a dataset (polling).
|
|
@@ -2379,6 +2381,11 @@ class ReactiveDatasetCache {
|
|
|
2379
2381
|
this.workspacePollers.delete(workspace);
|
|
2380
2382
|
}
|
|
2381
2383
|
}
|
|
2384
|
+
refresh(workspace) {
|
|
2385
|
+
if (this.destroyed) return Promise.resolve();
|
|
2386
|
+
if (!this.workspacePollers.has(workspace)) return Promise.resolve();
|
|
2387
|
+
return this.pollWorkspaceStatus(workspace);
|
|
2388
|
+
}
|
|
2382
2389
|
/**
|
|
2383
2390
|
* Poll workspace status and reconcile the cache with the server.
|
|
2384
2391
|
* Concurrent calls for the same workspace dedupe to a single fetch.
|
|
@@ -2443,7 +2450,7 @@ class ReactiveDatasetCache {
|
|
|
2443
2450
|
if (pending.length === 0) return;
|
|
2444
2451
|
const fetched = await Promise.allSettled(
|
|
2445
2452
|
pending.map(
|
|
2446
|
-
(p2) => p2.kind === "fetch" ? this.
|
|
2453
|
+
(p2) => p2.kind === "fetch" ? this.api.get(workspace, p2.path).then((result) => ({ p: p2, result })) : Promise.resolve({ p: p2, result: null })
|
|
2447
2454
|
)
|
|
2448
2455
|
);
|
|
2449
2456
|
if (this.destroyed) return;
|
|
@@ -2626,6 +2633,9 @@ class IndexedDBStagedAdapter {
|
|
|
2626
2633
|
req.onerror = () => reject2(req.error);
|
|
2627
2634
|
req.onblocked = () => reject2(new Error("IndexedDB open blocked"));
|
|
2628
2635
|
});
|
|
2636
|
+
void this.dbPromise.catch(() => {
|
|
2637
|
+
this.dbPromise = null;
|
|
2638
|
+
});
|
|
2629
2639
|
}
|
|
2630
2640
|
return this.dbPromise;
|
|
2631
2641
|
}
|
|
@@ -2701,6 +2711,11 @@ class StagedStore {
|
|
|
2701
2711
|
__publicField(this, "adapter");
|
|
2702
2712
|
__publicField(this, "hydrated");
|
|
2703
2713
|
__publicField(this, "inFlight", /* @__PURE__ */ new Set());
|
|
2714
|
+
// Per-key persistence chain — serializes save/remove for a key so they
|
|
2715
|
+
// land in IndexedDB in call order (last write wins) instead of racing.
|
|
2716
|
+
__publicField(this, "saveChains", /* @__PURE__ */ new Map());
|
|
2717
|
+
// Listeners notified when a persistence op fails durably.
|
|
2718
|
+
__publicField(this, "errorListeners", /* @__PURE__ */ new Set());
|
|
2704
2719
|
this.adapter = adapter;
|
|
2705
2720
|
this.hydrated = this.hydrate();
|
|
2706
2721
|
}
|
|
@@ -2737,14 +2752,14 @@ class StagedStore {
|
|
|
2737
2752
|
snapshot: next2.snapshot,
|
|
2738
2753
|
buffered: next2.buffered
|
|
2739
2754
|
};
|
|
2740
|
-
this.
|
|
2755
|
+
this.persist(key, () => this.adapter.save(key, persisted));
|
|
2741
2756
|
}
|
|
2742
2757
|
discard(workspace, path2) {
|
|
2743
2758
|
const key = datasetCacheKey(workspace, path2);
|
|
2744
2759
|
if (!this.entries.has(key)) return false;
|
|
2745
2760
|
this.entries.delete(key);
|
|
2746
2761
|
this.notify(key);
|
|
2747
|
-
this.
|
|
2762
|
+
this.persist(key, () => this.adapter.remove(key));
|
|
2748
2763
|
return true;
|
|
2749
2764
|
}
|
|
2750
2765
|
listKeys() {
|
|
@@ -2765,11 +2780,18 @@ class StagedStore {
|
|
|
2765
2780
|
getKeyVersion(key) {
|
|
2766
2781
|
return this.versions.get(key) ?? 0;
|
|
2767
2782
|
}
|
|
2783
|
+
onPersistError(cb) {
|
|
2784
|
+
this.errorListeners.add(cb);
|
|
2785
|
+
return () => {
|
|
2786
|
+
this.errorListeners.delete(cb);
|
|
2787
|
+
};
|
|
2788
|
+
}
|
|
2768
2789
|
/** Test-only: clear in-memory + persisted state. */
|
|
2769
2790
|
async clear() {
|
|
2770
2791
|
const keys = [...this.entries.keys()];
|
|
2771
2792
|
this.entries.clear();
|
|
2772
2793
|
for (const key of keys) this.notify(key);
|
|
2794
|
+
await this.flushPending();
|
|
2773
2795
|
await this.adapter.clear();
|
|
2774
2796
|
}
|
|
2775
2797
|
// ----- internals -------------------------------------------------------
|
|
@@ -2778,20 +2800,45 @@ class StagedStore {
|
|
|
2778
2800
|
const subs = this.subscribers.get(key);
|
|
2779
2801
|
if (subs) for (const cb of subs) cb();
|
|
2780
2802
|
}
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2803
|
+
/**
|
|
2804
|
+
* Serialize a persistence op behind any prior op for the same key, so they
|
|
2805
|
+
* land in IndexedDB in call order (last write wins) rather than racing.
|
|
2806
|
+
* Tracks the op for {@link flushPending} and routes failures to
|
|
2807
|
+
* {@link onPersistError} listeners (falling back to a console warning).
|
|
2808
|
+
*/
|
|
2809
|
+
persist(key, op) {
|
|
2810
|
+
const prev2 = this.saveChains.get(key) ?? Promise.resolve();
|
|
2811
|
+
const settled = prev2.then(op, op).then(
|
|
2812
|
+
() => void 0,
|
|
2813
|
+
(err) => {
|
|
2814
|
+
this.emitPersistError(key, err);
|
|
2815
|
+
}
|
|
2816
|
+
).then(() => {
|
|
2817
|
+
if (this.saveChains.get(key) === settled) this.saveChains.delete(key);
|
|
2818
|
+
this.inFlight.delete(settled);
|
|
2786
2819
|
});
|
|
2787
|
-
this.
|
|
2820
|
+
this.saveChains.set(key, settled);
|
|
2821
|
+
this.inFlight.add(settled);
|
|
2822
|
+
}
|
|
2823
|
+
emitPersistError(key, err) {
|
|
2824
|
+
if (this.errorListeners.size === 0) {
|
|
2825
|
+
console.warn("[StagedStore] persistence operation failed:", err);
|
|
2826
|
+
return;
|
|
2827
|
+
}
|
|
2828
|
+
for (const cb of [...this.errorListeners]) {
|
|
2829
|
+
try {
|
|
2830
|
+
cb(key, err);
|
|
2831
|
+
} catch (listenerErr) {
|
|
2832
|
+
console.warn("[StagedStore] persist-error listener threw:", listenerErr);
|
|
2833
|
+
}
|
|
2834
|
+
}
|
|
2788
2835
|
}
|
|
2789
2836
|
async hydrate() {
|
|
2790
2837
|
let persisted;
|
|
2791
2838
|
try {
|
|
2792
2839
|
persisted = await this.adapter.loadAll();
|
|
2793
2840
|
} catch (err) {
|
|
2794
|
-
|
|
2841
|
+
this.emitPersistError("", err);
|
|
2795
2842
|
return;
|
|
2796
2843
|
}
|
|
2797
2844
|
for (const [key, p2] of persisted) {
|
|
@@ -2827,7 +2874,7 @@ function clearStagedStoreSingleton() {
|
|
|
2827
2874
|
}
|
|
2828
2875
|
const UNCHANGED_VARIANT = east.variant("unchanged", null);
|
|
2829
2876
|
const blobEqual = east.equalFor(east.BlobType);
|
|
2830
|
-
const eastTypeEqual$
|
|
2877
|
+
const eastTypeEqual$2 = east.equalFor(internal$1.EastTypeType);
|
|
2831
2878
|
const helpersCache = new east.SortedMap(
|
|
2832
2879
|
void 0,
|
|
2833
2880
|
east.compareFor(internal$1.EastTypeType)
|
|
@@ -2880,6 +2927,7 @@ class BindRuntime {
|
|
|
2880
2927
|
// List cache helpers.
|
|
2881
2928
|
__publicField(this, "listCache", /* @__PURE__ */ new Map());
|
|
2882
2929
|
this.staged = staged;
|
|
2930
|
+
this.staged.onPersistError((_key, err) => this.emitWriteError(err));
|
|
2883
2931
|
}
|
|
2884
2932
|
// ----- cache singleton ------------------------------------------------
|
|
2885
2933
|
/** Read the active cache. Throws if none has been initialized. */
|
|
@@ -2917,6 +2965,16 @@ class BindRuntime {
|
|
|
2917
2965
|
this.writeErrorListeners.delete(cb);
|
|
2918
2966
|
};
|
|
2919
2967
|
}
|
|
2968
|
+
/** Fan a write/persistence error out to every registered listener. */
|
|
2969
|
+
emitWriteError(error3) {
|
|
2970
|
+
for (const cb of this.writeErrorListeners) {
|
|
2971
|
+
try {
|
|
2972
|
+
cb(error3);
|
|
2973
|
+
} catch (cbErr) {
|
|
2974
|
+
console.error("Data.bind write-error listener threw:", cbErr);
|
|
2975
|
+
}
|
|
2976
|
+
}
|
|
2977
|
+
}
|
|
2920
2978
|
/** Resolve once every currently-queued write has finished
|
|
2921
2979
|
* (success or failure). Errors are NOT thrown — subscribe via
|
|
2922
2980
|
* {@link onWriteError} for those. */
|
|
@@ -2954,13 +3012,7 @@ class BindRuntime {
|
|
|
2954
3012
|
await writeFn();
|
|
2955
3013
|
} catch (error3) {
|
|
2956
3014
|
console.error("Data.bind write failed:", error3);
|
|
2957
|
-
|
|
2958
|
-
try {
|
|
2959
|
-
cb(error3);
|
|
2960
|
-
} catch (cbErr) {
|
|
2961
|
-
console.error("Data.bind write-error listener threw:", cbErr);
|
|
2962
|
-
}
|
|
2963
|
-
}
|
|
3015
|
+
this.emitWriteError(error3);
|
|
2964
3016
|
}
|
|
2965
3017
|
}
|
|
2966
3018
|
this.isProcessingWrites = false;
|
|
@@ -3017,7 +3069,7 @@ class BindRuntime {
|
|
|
3017
3069
|
return;
|
|
3018
3070
|
}
|
|
3019
3071
|
const shapeChanged = existing.mode !== info.mode || existing.hasPatchDataset !== info.hasPatchDataset;
|
|
3020
|
-
const typeChanged = !eastTypeEqual$
|
|
3072
|
+
const typeChanged = !eastTypeEqual$2(existing.sourceType, info.sourceType);
|
|
3021
3073
|
if (!shapeChanged && !typeChanged) {
|
|
3022
3074
|
this.bindingRegistry.set(key, info);
|
|
3023
3075
|
return;
|
|
@@ -3120,6 +3172,10 @@ class BindRuntime {
|
|
|
3120
3172
|
}
|
|
3121
3173
|
return null;
|
|
3122
3174
|
};
|
|
3175
|
+
const startLaunch = () => {
|
|
3176
|
+
this.queueWrite(() => cache3.launchDataflow(ws));
|
|
3177
|
+
return null;
|
|
3178
|
+
};
|
|
3123
3179
|
if (mode === "direct" && !patchPath) {
|
|
3124
3180
|
return {
|
|
3125
3181
|
read: () => {
|
|
@@ -3134,6 +3190,7 @@ class BindRuntime {
|
|
|
3134
3190
|
this.queueWrite(() => cache3.writeAndStart(ws, sourcePath, encodeT(value)));
|
|
3135
3191
|
return null;
|
|
3136
3192
|
},
|
|
3193
|
+
start: startLaunch,
|
|
3137
3194
|
source: () => {
|
|
3138
3195
|
this.trackPath(ws, sourcePath);
|
|
3139
3196
|
return readSourceValue();
|
|
@@ -3167,6 +3224,7 @@ class BindRuntime {
|
|
|
3167
3224
|
this.queueWrite(() => cache3.writeAndStart(ws, pPath2, encodePatch(next2)));
|
|
3168
3225
|
return null;
|
|
3169
3226
|
},
|
|
3227
|
+
start: startLaunch,
|
|
3170
3228
|
source: () => {
|
|
3171
3229
|
this.trackPath(ws, sourcePath);
|
|
3172
3230
|
return readSourceValue();
|
|
@@ -3180,12 +3238,8 @@ class BindRuntime {
|
|
|
3180
3238
|
const patchVal = readPatchValue();
|
|
3181
3239
|
this.queueWrite(async () => {
|
|
3182
3240
|
const next2 = apply2(sourceVal, patchVal);
|
|
3183
|
-
|
|
3184
|
-
cache3.
|
|
3185
|
-
writes.push(cache3.write(ws, sourcePath, encodeT(next2)));
|
|
3186
|
-
writes.push(cache3.write(ws, pPath2, encodePatch(UNCHANGED_VARIANT)));
|
|
3187
|
-
});
|
|
3188
|
-
await Promise.all(writes);
|
|
3241
|
+
await cache3.write(ws, sourcePath, encodeT(next2));
|
|
3242
|
+
await cache3.write(ws, pPath2, encodePatch(UNCHANGED_VARIANT));
|
|
3189
3243
|
});
|
|
3190
3244
|
return null;
|
|
3191
3245
|
},
|
|
@@ -3211,6 +3265,7 @@ class BindRuntime {
|
|
|
3211
3265
|
},
|
|
3212
3266
|
write: writeStaged,
|
|
3213
3267
|
writeAndStart: writeStaged,
|
|
3268
|
+
start: startLaunch,
|
|
3214
3269
|
source: () => {
|
|
3215
3270
|
this.trackPath(ws, sourcePath);
|
|
3216
3271
|
return readSourceValue();
|
|
@@ -3255,6 +3310,7 @@ class BindRuntime {
|
|
|
3255
3310
|
},
|
|
3256
3311
|
write: writeStaged,
|
|
3257
3312
|
writeAndStart: writeStaged,
|
|
3313
|
+
start: startLaunch,
|
|
3258
3314
|
source: () => {
|
|
3259
3315
|
this.trackPath(ws, sourcePath);
|
|
3260
3316
|
return readSourceValue();
|
|
@@ -3403,6 +3459,110 @@ platform.registerReactiveTracker({
|
|
|
3403
3459
|
}
|
|
3404
3460
|
});
|
|
3405
3461
|
platform.registerPlatformImplementation(BindPlatform);
|
|
3462
|
+
class TrackedChannelStore {
|
|
3463
|
+
constructor() {
|
|
3464
|
+
__publicField(this, "entries", /* @__PURE__ */ new Map());
|
|
3465
|
+
// Per-key reactive subscription shim.
|
|
3466
|
+
__publicField(this, "keySubscribers", /* @__PURE__ */ new Map());
|
|
3467
|
+
__publicField(this, "keyVersions", /* @__PURE__ */ new Map());
|
|
3468
|
+
// Reactive tracking — read closures push their channel keys here while a
|
|
3469
|
+
// Reactive.Root render is being tracked.
|
|
3470
|
+
__publicField(this, "trackingContext", null);
|
|
3471
|
+
}
|
|
3472
|
+
// ----- reactive tracking ----------------------------------------------
|
|
3473
|
+
enableTracking() {
|
|
3474
|
+
this.trackingContext = /* @__PURE__ */ new Set();
|
|
3475
|
+
return this.trackingContext;
|
|
3476
|
+
}
|
|
3477
|
+
disableTracking() {
|
|
3478
|
+
const keys = this.trackingContext ? [...this.trackingContext] : [];
|
|
3479
|
+
this.trackingContext = null;
|
|
3480
|
+
return keys;
|
|
3481
|
+
}
|
|
3482
|
+
isTracking() {
|
|
3483
|
+
return this.trackingContext !== null;
|
|
3484
|
+
}
|
|
3485
|
+
/** Record a channel-key dependency for the current render (no-op when not
|
|
3486
|
+
* tracking). */
|
|
3487
|
+
track(key) {
|
|
3488
|
+
var _a2;
|
|
3489
|
+
(_a2 = this.trackingContext) == null ? void 0 : _a2.add(key);
|
|
3490
|
+
}
|
|
3491
|
+
// ----- subscription shim ------------------------------------------------
|
|
3492
|
+
subscribe(key, callback) {
|
|
3493
|
+
let subs = this.keySubscribers.get(key);
|
|
3494
|
+
if (!subs) {
|
|
3495
|
+
subs = /* @__PURE__ */ new Set();
|
|
3496
|
+
this.keySubscribers.set(key, subs);
|
|
3497
|
+
}
|
|
3498
|
+
subs.add(callback);
|
|
3499
|
+
return () => {
|
|
3500
|
+
subs.delete(callback);
|
|
3501
|
+
if (subs.size === 0 && this.keySubscribers.get(key) === subs) {
|
|
3502
|
+
this.keySubscribers.delete(key);
|
|
3503
|
+
}
|
|
3504
|
+
};
|
|
3505
|
+
}
|
|
3506
|
+
getKeyVersion(key) {
|
|
3507
|
+
return this.keyVersions.get(key) ?? 0;
|
|
3508
|
+
}
|
|
3509
|
+
notify(key) {
|
|
3510
|
+
this.keyVersions.set(key, (this.keyVersions.get(key) ?? 0) + 1);
|
|
3511
|
+
const subs = this.keySubscribers.get(key);
|
|
3512
|
+
if (subs) for (const cb of [...subs]) cb();
|
|
3513
|
+
}
|
|
3514
|
+
// ----- channel registry + latest-wins latch ----------------------------
|
|
3515
|
+
entry(key) {
|
|
3516
|
+
let entry = this.entries.get(key);
|
|
3517
|
+
if (!entry) {
|
|
3518
|
+
entry = this.createEntry();
|
|
3519
|
+
this.entries.set(key, entry);
|
|
3520
|
+
}
|
|
3521
|
+
return entry;
|
|
3522
|
+
}
|
|
3523
|
+
/**
|
|
3524
|
+
* Open a latest-wins launch on a channel: bump the seq, mark the entry
|
|
3525
|
+
* `running`, optionally `reset` it (e.g. clear a prior error), notify, and
|
|
3526
|
+
* return a `settle` that applies a terminal mutation only if this launch is
|
|
3527
|
+
* still the current one (a superseded / cancelled launch settles to a
|
|
3528
|
+
* no-op).
|
|
3529
|
+
*/
|
|
3530
|
+
beginLaunch(key, reset2) {
|
|
3531
|
+
const entry = this.entry(key);
|
|
3532
|
+
entry.launchSeq += 1;
|
|
3533
|
+
const mySeq = entry.launchSeq;
|
|
3534
|
+
entry.status = "running";
|
|
3535
|
+
reset2 == null ? void 0 : reset2(entry);
|
|
3536
|
+
this.notify(key);
|
|
3537
|
+
const settle = (mutate) => {
|
|
3538
|
+
const current = this.entries.get(key);
|
|
3539
|
+
if (!current || current.launchSeq !== mySeq) return;
|
|
3540
|
+
mutate(current);
|
|
3541
|
+
this.notify(key);
|
|
3542
|
+
};
|
|
3543
|
+
return { entry, settle };
|
|
3544
|
+
}
|
|
3545
|
+
/**
|
|
3546
|
+
* Client-side cancel: if the channel is running, orphan the in-flight wait
|
|
3547
|
+
* (bump the seq) and mark it `cancelled`. `after` runs before the notify,
|
|
3548
|
+
* for subclass-specific cleanup (e.g. dropping an in-flight handle).
|
|
3549
|
+
*/
|
|
3550
|
+
cancelChannel(key, after) {
|
|
3551
|
+
const entry = this.entries.get(key);
|
|
3552
|
+
if (entry && entry.status === "running") {
|
|
3553
|
+
entry.launchSeq += 1;
|
|
3554
|
+
entry.status = "cancelled";
|
|
3555
|
+
after == null ? void 0 : after(entry);
|
|
3556
|
+
this.notify(key);
|
|
3557
|
+
}
|
|
3558
|
+
}
|
|
3559
|
+
/** Drop all channel state (entries + subscriptions + versions). */
|
|
3560
|
+
clearChannels() {
|
|
3561
|
+
this.entries.clear();
|
|
3562
|
+
this.keySubscribers.clear();
|
|
3563
|
+
this.keyVersions.clear();
|
|
3564
|
+
}
|
|
3565
|
+
}
|
|
3406
3566
|
function createDefaultFunctionApi(apiUrl, repo, getToken) {
|
|
3407
3567
|
const opts = () => ({ token: getToken() });
|
|
3408
3568
|
return {
|
|
@@ -3418,8 +3578,8 @@ function createDefaultFunctionApi(apiUrl, repo, getToken) {
|
|
|
3418
3578
|
}
|
|
3419
3579
|
};
|
|
3420
3580
|
}
|
|
3421
|
-
const eastTypeEqual = east.equalFor(internal$1.EastTypeType);
|
|
3422
|
-
function
|
|
3581
|
+
const eastTypeEqual$1 = east.equalFor(internal$1.EastTypeType);
|
|
3582
|
+
function signatureOfFuncHandleType(handleType) {
|
|
3423
3583
|
var _a2, _b2;
|
|
3424
3584
|
if (handleType.type !== "Struct") {
|
|
3425
3585
|
throw new Error(`Func.bind: handle type must be a Struct; got ${handleType.type}`);
|
|
@@ -3478,10 +3638,10 @@ function errorOfExecuteResult(result) {
|
|
|
3478
3638
|
stderr: result.stderr
|
|
3479
3639
|
};
|
|
3480
3640
|
default:
|
|
3481
|
-
return transportError(`unexpected outcome "${outcome.type}"`);
|
|
3641
|
+
return transportError$1(`unexpected outcome "${outcome.type}"`);
|
|
3482
3642
|
}
|
|
3483
3643
|
}
|
|
3484
|
-
function transportError(message) {
|
|
3644
|
+
function transportError$1(message) {
|
|
3485
3645
|
return {
|
|
3486
3646
|
kind: east.variant("transport", { message }),
|
|
3487
3647
|
message,
|
|
@@ -3492,20 +3652,16 @@ function transportError(message) {
|
|
|
3492
3652
|
function funcChannelKey(workspace, name) {
|
|
3493
3653
|
return `func:${workspace}:${name}`;
|
|
3494
3654
|
}
|
|
3495
|
-
class FuncRuntime {
|
|
3655
|
+
class FuncRuntime extends TrackedChannelStore {
|
|
3496
3656
|
constructor() {
|
|
3657
|
+
super(...arguments);
|
|
3497
3658
|
__publicField(this, "api", null);
|
|
3498
3659
|
__publicField(this, "workspace", null);
|
|
3499
|
-
__publicField(this, "entries", /* @__PURE__ */ new Map());
|
|
3500
3660
|
// Signature lists are fetched once per workspace and cached.
|
|
3501
3661
|
__publicField(this, "signatureLists", /* @__PURE__ */ new Map());
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
__publicField(this, "keyVersions", /* @__PURE__ */ new Map());
|
|
3506
|
-
// Reactive tracking — read closures push their channel keys here while
|
|
3507
|
-
// a Reactive.Root render is being tracked.
|
|
3508
|
-
__publicField(this, "trackingContext", null);
|
|
3662
|
+
}
|
|
3663
|
+
createEntry() {
|
|
3664
|
+
return { status: "idle", launchSeq: 0 };
|
|
3509
3665
|
}
|
|
3510
3666
|
// ----- wiring ----------------------------------------------------------
|
|
3511
3667
|
/** Install the API adapter + workspace — called by the React provider
|
|
@@ -3518,59 +3674,8 @@ class FuncRuntime {
|
|
|
3518
3674
|
clear() {
|
|
3519
3675
|
this.api = null;
|
|
3520
3676
|
this.workspace = null;
|
|
3521
|
-
this.
|
|
3677
|
+
this.clearChannels();
|
|
3522
3678
|
this.signatureLists.clear();
|
|
3523
|
-
this.keySubscribers.clear();
|
|
3524
|
-
this.keyVersions.clear();
|
|
3525
|
-
}
|
|
3526
|
-
// ----- reactive tracking ----------------------------------------------
|
|
3527
|
-
enableTracking() {
|
|
3528
|
-
this.trackingContext = /* @__PURE__ */ new Set();
|
|
3529
|
-
return this.trackingContext;
|
|
3530
|
-
}
|
|
3531
|
-
disableTracking() {
|
|
3532
|
-
const keys = this.trackingContext ? [...this.trackingContext] : [];
|
|
3533
|
-
this.trackingContext = null;
|
|
3534
|
-
return keys;
|
|
3535
|
-
}
|
|
3536
|
-
isTracking() {
|
|
3537
|
-
return this.trackingContext !== null;
|
|
3538
|
-
}
|
|
3539
|
-
track(key) {
|
|
3540
|
-
var _a2;
|
|
3541
|
-
(_a2 = this.trackingContext) == null ? void 0 : _a2.add(key);
|
|
3542
|
-
}
|
|
3543
|
-
// ----- subscription shim ------------------------------------------------
|
|
3544
|
-
subscribe(key, callback) {
|
|
3545
|
-
let subs = this.keySubscribers.get(key);
|
|
3546
|
-
if (!subs) {
|
|
3547
|
-
subs = /* @__PURE__ */ new Set();
|
|
3548
|
-
this.keySubscribers.set(key, subs);
|
|
3549
|
-
}
|
|
3550
|
-
subs.add(callback);
|
|
3551
|
-
return () => {
|
|
3552
|
-
subs.delete(callback);
|
|
3553
|
-
if (subs.size === 0 && this.keySubscribers.get(key) === subs) {
|
|
3554
|
-
this.keySubscribers.delete(key);
|
|
3555
|
-
}
|
|
3556
|
-
};
|
|
3557
|
-
}
|
|
3558
|
-
getKeyVersion(key) {
|
|
3559
|
-
return this.keyVersions.get(key) ?? 0;
|
|
3560
|
-
}
|
|
3561
|
-
notify(key) {
|
|
3562
|
-
this.keyVersions.set(key, (this.keyVersions.get(key) ?? 0) + 1);
|
|
3563
|
-
const subs = this.keySubscribers.get(key);
|
|
3564
|
-
if (subs) for (const cb of [...subs]) cb();
|
|
3565
|
-
}
|
|
3566
|
-
// ----- registry ----------------------------------------------------------
|
|
3567
|
-
entry(key) {
|
|
3568
|
-
let entry = this.entries.get(key);
|
|
3569
|
-
if (!entry) {
|
|
3570
|
-
entry = { status: "idle", launchSeq: 0 };
|
|
3571
|
-
this.entries.set(key, entry);
|
|
3572
|
-
}
|
|
3573
|
-
return entry;
|
|
3574
3679
|
}
|
|
3575
3680
|
/** The deployed signature list for a workspace (fetched once). */
|
|
3576
3681
|
signatures(workspace) {
|
|
@@ -3593,7 +3698,7 @@ class FuncRuntime {
|
|
|
3593
3698
|
try {
|
|
3594
3699
|
list = await this.signatures(workspace);
|
|
3595
3700
|
} catch (err) {
|
|
3596
|
-
return transportError(`failed to list workspace functions: ${err instanceof Error ? err.message : String(err)}`);
|
|
3701
|
+
return transportError$1(`failed to list workspace functions: ${err instanceof Error ? err.message : String(err)}`);
|
|
3597
3702
|
}
|
|
3598
3703
|
const deployed = list.find((f2) => f2.name === name);
|
|
3599
3704
|
if (!deployed) {
|
|
@@ -3604,8 +3709,8 @@ class FuncRuntime {
|
|
|
3604
3709
|
stderr: ""
|
|
3605
3710
|
};
|
|
3606
3711
|
}
|
|
3607
|
-
const inputsMatch = deployed.inputTypes.length === sig.inputs.length && deployed.inputTypes.every((t4, i) => eastTypeEqual(t4, sig.inputs[i]));
|
|
3608
|
-
const outputMatches = eastTypeEqual(deployed.outputType, sig.output);
|
|
3712
|
+
const inputsMatch = deployed.inputTypes.length === sig.inputs.length && deployed.inputTypes.every((t4, i) => eastTypeEqual$1(t4, sig.inputs[i]));
|
|
3713
|
+
const outputMatches = eastTypeEqual$1(deployed.outputType, sig.output);
|
|
3609
3714
|
if (!inputsMatch || !outputMatches) {
|
|
3610
3715
|
const message = `signature mismatch for "${name}": bound (${sig.inputs.length} inputs) disagrees with the deployed package`;
|
|
3611
3716
|
return {
|
|
@@ -3620,17 +3725,7 @@ class FuncRuntime {
|
|
|
3620
3725
|
// ----- closure semantics -------------------------------------------------
|
|
3621
3726
|
launch(workspace, name, sig, args) {
|
|
3622
3727
|
const key = funcChannelKey(workspace, name);
|
|
3623
|
-
const
|
|
3624
|
-
entry.launchSeq += 1;
|
|
3625
|
-
const mySeq = entry.launchSeq;
|
|
3626
|
-
entry.status = "running";
|
|
3627
|
-
this.notify(key);
|
|
3628
|
-
const settle = (mutate) => {
|
|
3629
|
-
const current = this.entries.get(key);
|
|
3630
|
-
if (!current || current.launchSeq !== mySeq) return;
|
|
3631
|
-
mutate(current);
|
|
3632
|
-
this.notify(key);
|
|
3633
|
-
};
|
|
3728
|
+
const { settle } = this.beginLaunch(key);
|
|
3634
3729
|
void (async () => {
|
|
3635
3730
|
const invalid = await this.validate(workspace, name, sig);
|
|
3636
3731
|
if (invalid) {
|
|
@@ -3644,7 +3739,7 @@ class FuncRuntime {
|
|
|
3644
3739
|
if (!api3) {
|
|
3645
3740
|
settle((e3) => {
|
|
3646
3741
|
e3.status = "failed";
|
|
3647
|
-
e3.error = transportError("no FunctionApi installed");
|
|
3742
|
+
e3.error = transportError$1("no FunctionApi installed");
|
|
3648
3743
|
});
|
|
3649
3744
|
return;
|
|
3650
3745
|
}
|
|
@@ -3655,7 +3750,7 @@ class FuncRuntime {
|
|
|
3655
3750
|
} catch (err) {
|
|
3656
3751
|
settle((e3) => {
|
|
3657
3752
|
e3.status = "failed";
|
|
3658
|
-
e3.error = transportError(err instanceof Error ? err.message : String(err));
|
|
3753
|
+
e3.error = transportError$1(err instanceof Error ? err.message : String(err));
|
|
3659
3754
|
});
|
|
3660
3755
|
return;
|
|
3661
3756
|
}
|
|
@@ -3666,7 +3761,7 @@ class FuncRuntime {
|
|
|
3666
3761
|
} catch (err) {
|
|
3667
3762
|
settle((e3) => {
|
|
3668
3763
|
e3.status = "failed";
|
|
3669
|
-
e3.error = transportError(`failed to decode result: ${err instanceof Error ? err.message : String(err)}`);
|
|
3764
|
+
e3.error = transportError$1(`failed to decode result: ${err instanceof Error ? err.message : String(err)}`);
|
|
3670
3765
|
});
|
|
3671
3766
|
return;
|
|
3672
3767
|
}
|
|
@@ -3686,7 +3781,7 @@ class FuncRuntime {
|
|
|
3686
3781
|
}
|
|
3687
3782
|
/** Build the handle value for one `Func.bind` platform evaluation. */
|
|
3688
3783
|
buildHandle(handleType, name) {
|
|
3689
|
-
const sig =
|
|
3784
|
+
const sig = signatureOfFuncHandleType(handleType);
|
|
3690
3785
|
const runtime = this;
|
|
3691
3786
|
const resolveWorkspace = () => {
|
|
3692
3787
|
if (!runtime.workspace) {
|
|
@@ -3724,12 +3819,8 @@ class FuncRuntime {
|
|
|
3724
3819
|
return entry.status === "running";
|
|
3725
3820
|
},
|
|
3726
3821
|
cancel: () => {
|
|
3727
|
-
const { key
|
|
3728
|
-
|
|
3729
|
-
entry.launchSeq += 1;
|
|
3730
|
-
entry.status = "cancelled";
|
|
3731
|
-
runtime.notify(key);
|
|
3732
|
-
}
|
|
3822
|
+
const { key } = channel();
|
|
3823
|
+
runtime.cancelChannel(key);
|
|
3733
3824
|
return null;
|
|
3734
3825
|
},
|
|
3735
3826
|
binding: { name }
|
|
@@ -7469,6 +7560,430 @@ var faCircleInfo = {
|
|
|
7469
7560
|
iconName: "circle-info",
|
|
7470
7561
|
icon: [512, 512, ["info-circle"], "f05a", "M256 512a256 256 0 1 0 0-512 256 256 0 1 0 0 512zM224 160a32 32 0 1 1 64 0 32 32 0 1 1 -64 0zm-8 64l48 0c13.3 0 24 10.7 24 24l0 88 8 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-80 0c-13.3 0-24-10.7-24-24s10.7-24 24-24l24 0 0-64-24 0c-13.3 0-24-10.7-24-24s10.7-24 24-24z"]
|
|
7471
7562
|
};
|
|
7563
|
+
function createDefaultRecordApi(apiUrl, repo, getToken) {
|
|
7564
|
+
const opts = () => ({ token: getToken() });
|
|
7565
|
+
return {
|
|
7566
|
+
async describe(workspace, record) {
|
|
7567
|
+
return e3ApiClient.workspaceRecordDescribe(apiUrl, repo, workspace, record, opts());
|
|
7568
|
+
},
|
|
7569
|
+
async mutate(workspace, record, mutation, req) {
|
|
7570
|
+
return e3ApiClient.workspaceRecordMutate(apiUrl, repo, workspace, record, mutation, {
|
|
7571
|
+
args: req.args,
|
|
7572
|
+
actor: east.none,
|
|
7573
|
+
limits: east.none
|
|
7574
|
+
}, opts());
|
|
7575
|
+
},
|
|
7576
|
+
async history(workspace, record, limit2, from2) {
|
|
7577
|
+
return e3ApiClient.workspaceRecordHistory(apiUrl, repo, workspace, record, limit2, opts(), from2);
|
|
7578
|
+
}
|
|
7579
|
+
};
|
|
7580
|
+
}
|
|
7581
|
+
const eastTypeEqual = east.equalFor(internal$1.EastTypeType);
|
|
7582
|
+
const RESERVED_MUTATE_FIELDS = /* @__PURE__ */ new Set(["pending", "status", "error", "cancel"]);
|
|
7583
|
+
function signatureOfRecordHandleType(handleType) {
|
|
7584
|
+
var _a2, _b2;
|
|
7585
|
+
if (handleType.type !== "Struct") {
|
|
7586
|
+
throw new Error(`Record.bind: handle type must be a Struct; got ${handleType.type}`);
|
|
7587
|
+
}
|
|
7588
|
+
const fields = handleType.value;
|
|
7589
|
+
const read = (_a2 = fields.find((f2) => f2.name === "read")) == null ? void 0 : _a2.type;
|
|
7590
|
+
const mutate = (_b2 = fields.find((f2) => f2.name === "mutate")) == null ? void 0 : _b2.type;
|
|
7591
|
+
if ((read == null ? void 0 : read.type) !== "Function") {
|
|
7592
|
+
throw new Error("Record.bind: handle type is missing its read closure");
|
|
7593
|
+
}
|
|
7594
|
+
if ((mutate == null ? void 0 : mutate.type) !== "Struct") {
|
|
7595
|
+
throw new Error("Record.bind: handle type is missing its mutate struct");
|
|
7596
|
+
}
|
|
7597
|
+
const stateType = read.value.output;
|
|
7598
|
+
const mutations = /* @__PURE__ */ new Map();
|
|
7599
|
+
for (const field of mutate.value) {
|
|
7600
|
+
if (RESERVED_MUTATE_FIELDS.has(field.name)) continue;
|
|
7601
|
+
if (field.type.type !== "Function") {
|
|
7602
|
+
throw new Error(`Record.bind: mutate field "${field.name}" must be a closure`);
|
|
7603
|
+
}
|
|
7604
|
+
mutations.set(field.name, field.type.value.inputs);
|
|
7605
|
+
}
|
|
7606
|
+
return { stateType, mutations };
|
|
7607
|
+
}
|
|
7608
|
+
function errorOfMutationResult(result) {
|
|
7609
|
+
const outcome = result.outcome;
|
|
7610
|
+
switch (outcome.type) {
|
|
7611
|
+
case "invalid":
|
|
7612
|
+
return { kind: east.variant("invalid", { message: outcome.value.message }), message: outcome.value.message, stderr: "" };
|
|
7613
|
+
case "failed":
|
|
7614
|
+
return {
|
|
7615
|
+
kind: east.variant("failed", { exitCode: outcome.value.exitCode }),
|
|
7616
|
+
message: `reducer exited with code ${outcome.value.exitCode}`,
|
|
7617
|
+
stderr: outcome.value.stderr
|
|
7618
|
+
};
|
|
7619
|
+
case "too_large":
|
|
7620
|
+
return {
|
|
7621
|
+
kind: east.variant("too_large", { bytes: outcome.value.bytes, limit: outcome.value.limit }),
|
|
7622
|
+
message: `new state too large (${outcome.value.bytes} bytes, limit ${outcome.value.limit})`,
|
|
7623
|
+
stderr: outcome.value.stderr
|
|
7624
|
+
};
|
|
7625
|
+
case "timed_out":
|
|
7626
|
+
return {
|
|
7627
|
+
kind: east.variant("timed_out", { ms: outcome.value.ms }),
|
|
7628
|
+
message: `mutation timed out after ${outcome.value.ms}ms (server deadline)`,
|
|
7629
|
+
stderr: outcome.value.stderr
|
|
7630
|
+
};
|
|
7631
|
+
case "conflict":
|
|
7632
|
+
return {
|
|
7633
|
+
kind: east.variant("conflict", { attempts: outcome.value.attempts }),
|
|
7634
|
+
message: `compare-and-swap conflicted after ${outcome.value.attempts} attempts; try again`,
|
|
7635
|
+
stderr: ""
|
|
7636
|
+
};
|
|
7637
|
+
default:
|
|
7638
|
+
return transportError(`unexpected outcome "${outcome.type}"`);
|
|
7639
|
+
}
|
|
7640
|
+
}
|
|
7641
|
+
function transportError(message) {
|
|
7642
|
+
return { kind: east.variant("transport", { message }), message, stderr: "" };
|
|
7643
|
+
}
|
|
7644
|
+
function recordPath(name) {
|
|
7645
|
+
return [east.variant("field", "records"), east.variant("field", name)];
|
|
7646
|
+
}
|
|
7647
|
+
function recordChannelKey(workspace, name) {
|
|
7648
|
+
return `record:${workspace}:${name}`;
|
|
7649
|
+
}
|
|
7650
|
+
class RecordRuntime extends TrackedChannelStore {
|
|
7651
|
+
constructor() {
|
|
7652
|
+
super(...arguments);
|
|
7653
|
+
__publicField(this, "api", null);
|
|
7654
|
+
__publicField(this, "cache", null);
|
|
7655
|
+
__publicField(this, "workspace", null);
|
|
7656
|
+
// Describe signatures, fetched once per (workspace, record), failures evicted.
|
|
7657
|
+
__publicField(this, "signatureCache", /* @__PURE__ */ new Map());
|
|
7658
|
+
// History per channel, fetched once + refreshed on commit.
|
|
7659
|
+
__publicField(this, "histories", /* @__PURE__ */ new Map());
|
|
7660
|
+
__publicField(this, "historyInFlight", /* @__PURE__ */ new Set());
|
|
7661
|
+
// Channels whose last history fetch failed. Guards `history()` from
|
|
7662
|
+
// re-issuing the request on every render (a failing endpoint would
|
|
7663
|
+
// otherwise spin); cleared on the next commit / on clear() so a later
|
|
7664
|
+
// mutation retries.
|
|
7665
|
+
__publicField(this, "historyFailed", /* @__PURE__ */ new Set());
|
|
7666
|
+
}
|
|
7667
|
+
createEntry() {
|
|
7668
|
+
return { status: "idle", launchSeq: 0 };
|
|
7669
|
+
}
|
|
7670
|
+
// ----- wiring ----------------------------------------------------------
|
|
7671
|
+
/** Install the API adapter + dataset cache + workspace — called by the
|
|
7672
|
+
* React provider (or a test/showcase harness) before any handle is used. */
|
|
7673
|
+
initialize(api3, cache3, workspace) {
|
|
7674
|
+
this.api = api3;
|
|
7675
|
+
this.cache = cache3;
|
|
7676
|
+
this.workspace = workspace;
|
|
7677
|
+
}
|
|
7678
|
+
/** Tear down the adapter and all record state. */
|
|
7679
|
+
clear() {
|
|
7680
|
+
this.api = null;
|
|
7681
|
+
this.cache = null;
|
|
7682
|
+
this.workspace = null;
|
|
7683
|
+
this.clearChannels();
|
|
7684
|
+
this.signatureCache.clear();
|
|
7685
|
+
this.histories.clear();
|
|
7686
|
+
this.historyInFlight.clear();
|
|
7687
|
+
this.historyFailed.clear();
|
|
7688
|
+
}
|
|
7689
|
+
resolveWorkspace() {
|
|
7690
|
+
if (!this.workspace) {
|
|
7691
|
+
throw new Error("Record.bind: no workspace configured — mount a provider (or call initializeRecordApi) first");
|
|
7692
|
+
}
|
|
7693
|
+
return this.workspace;
|
|
7694
|
+
}
|
|
7695
|
+
/** The deployed describe signature for a record (fetched once, evicted on failure). */
|
|
7696
|
+
signature(workspace, record) {
|
|
7697
|
+
const sigKey = `${workspace}:${record}`;
|
|
7698
|
+
let promise4 = this.signatureCache.get(sigKey);
|
|
7699
|
+
if (!promise4) {
|
|
7700
|
+
const api3 = this.api;
|
|
7701
|
+
if (!api3) return Promise.reject(new Error("Record.bind: no RecordApi installed"));
|
|
7702
|
+
promise4 = api3.describe(workspace, record).catch((err) => {
|
|
7703
|
+
this.signatureCache.delete(sigKey);
|
|
7704
|
+
throw err;
|
|
7705
|
+
});
|
|
7706
|
+
this.signatureCache.set(sigKey, promise4);
|
|
7707
|
+
}
|
|
7708
|
+
return promise4;
|
|
7709
|
+
}
|
|
7710
|
+
/** Validate a mutation's declared arg types against the deployed signature. */
|
|
7711
|
+
async validate(workspace, record, mutation, argTypes) {
|
|
7712
|
+
let sig;
|
|
7713
|
+
try {
|
|
7714
|
+
sig = await this.signature(workspace, record);
|
|
7715
|
+
} catch (err) {
|
|
7716
|
+
return transportError(`failed to describe record "${record}": ${err instanceof Error ? err.message : String(err)}`);
|
|
7717
|
+
}
|
|
7718
|
+
const deployed = sig.mutations.find((m2) => m2.name === mutation);
|
|
7719
|
+
if (!deployed) {
|
|
7720
|
+
const message = `no mutation "${mutation}" on record "${record}" in the deployed package`;
|
|
7721
|
+
return { kind: east.variant("invalid", { message }), message, stderr: "" };
|
|
7722
|
+
}
|
|
7723
|
+
const argsMatch = deployed.argTypes.length === argTypes.length && deployed.argTypes.every((t4, i) => eastTypeEqual(t4, argTypes[i]));
|
|
7724
|
+
if (!argsMatch) {
|
|
7725
|
+
const message = `signature mismatch for mutation "${mutation}": bound (${argTypes.length} args) disagrees with the deployed package`;
|
|
7726
|
+
return { kind: east.variant("invalid", { message }), message, stderr: "" };
|
|
7727
|
+
}
|
|
7728
|
+
return null;
|
|
7729
|
+
}
|
|
7730
|
+
/** Fetch a record's history once per channel (deduped); notify on settle. */
|
|
7731
|
+
fetchHistory(workspace, record, key) {
|
|
7732
|
+
if (this.historyInFlight.has(key)) return;
|
|
7733
|
+
this.historyInFlight.add(key);
|
|
7734
|
+
void (async () => {
|
|
7735
|
+
const api3 = this.api;
|
|
7736
|
+
try {
|
|
7737
|
+
if (!api3) throw new Error("no RecordApi installed");
|
|
7738
|
+
const result = await api3.history(workspace, record, void 0);
|
|
7739
|
+
this.histories.set(key, result.commits);
|
|
7740
|
+
this.historyFailed.delete(key);
|
|
7741
|
+
} catch {
|
|
7742
|
+
this.historyFailed.add(key);
|
|
7743
|
+
} finally {
|
|
7744
|
+
this.historyInFlight.delete(key);
|
|
7745
|
+
this.notify(key);
|
|
7746
|
+
}
|
|
7747
|
+
})();
|
|
7748
|
+
}
|
|
7749
|
+
// ----- closure semantics -------------------------------------------------
|
|
7750
|
+
launchMutation(workspace, record, mutation, argTypes, args) {
|
|
7751
|
+
const key = recordChannelKey(workspace, record);
|
|
7752
|
+
const { entry, settle } = this.beginLaunch(key, (e3) => {
|
|
7753
|
+
delete e3.error;
|
|
7754
|
+
});
|
|
7755
|
+
const run = (async () => {
|
|
7756
|
+
var _a2;
|
|
7757
|
+
const invalid = await this.validate(workspace, record, mutation, argTypes);
|
|
7758
|
+
if (invalid) {
|
|
7759
|
+
settle((e3) => {
|
|
7760
|
+
e3.status = "failed";
|
|
7761
|
+
e3.error = invalid;
|
|
7762
|
+
});
|
|
7763
|
+
return;
|
|
7764
|
+
}
|
|
7765
|
+
const api3 = this.api;
|
|
7766
|
+
if (!api3) {
|
|
7767
|
+
settle((e3) => {
|
|
7768
|
+
e3.status = "failed";
|
|
7769
|
+
e3.error = transportError("no RecordApi installed");
|
|
7770
|
+
});
|
|
7771
|
+
return;
|
|
7772
|
+
}
|
|
7773
|
+
let result;
|
|
7774
|
+
try {
|
|
7775
|
+
const encoded = args.map((arg, i) => east.encodeBeast2For(argTypes[i])(arg));
|
|
7776
|
+
result = await api3.mutate(workspace, record, mutation, { args: encoded });
|
|
7777
|
+
} catch (err) {
|
|
7778
|
+
settle((e3) => {
|
|
7779
|
+
e3.status = "failed";
|
|
7780
|
+
e3.error = transportError(err instanceof Error ? err.message : String(err));
|
|
7781
|
+
});
|
|
7782
|
+
return;
|
|
7783
|
+
}
|
|
7784
|
+
if (result.outcome.type === "committed") {
|
|
7785
|
+
settle((e3) => {
|
|
7786
|
+
e3.status = "committed";
|
|
7787
|
+
delete e3.error;
|
|
7788
|
+
});
|
|
7789
|
+
void ((_a2 = this.cache) == null ? void 0 : _a2.refresh(workspace));
|
|
7790
|
+
this.histories.delete(key);
|
|
7791
|
+
this.historyFailed.delete(key);
|
|
7792
|
+
this.notify(key);
|
|
7793
|
+
} else {
|
|
7794
|
+
settle((e3) => {
|
|
7795
|
+
e3.status = "failed";
|
|
7796
|
+
e3.error = errorOfMutationResult(result);
|
|
7797
|
+
});
|
|
7798
|
+
}
|
|
7799
|
+
})();
|
|
7800
|
+
entry.inflight = run;
|
|
7801
|
+
void run.finally(() => {
|
|
7802
|
+
const current = this.entries.get(key);
|
|
7803
|
+
if (current && current.inflight === run) delete current.inflight;
|
|
7804
|
+
});
|
|
7805
|
+
}
|
|
7806
|
+
/** Build the handle value for one `Record.bind` platform evaluation. */
|
|
7807
|
+
buildHandle(handleType, name) {
|
|
7808
|
+
const sig = signatureOfRecordHandleType(handleType);
|
|
7809
|
+
const decodeState = east.decodeBeast2For(sig.stateType);
|
|
7810
|
+
const runtime = this;
|
|
7811
|
+
const path2 = recordPath(name);
|
|
7812
|
+
const requireCache = () => {
|
|
7813
|
+
if (!runtime.cache) {
|
|
7814
|
+
throw new Error("Record.bind: no dataset cache configured — mount a provider first");
|
|
7815
|
+
}
|
|
7816
|
+
return runtime.cache;
|
|
7817
|
+
};
|
|
7818
|
+
const mutate = {
|
|
7819
|
+
pending: () => {
|
|
7820
|
+
const ws = runtime.resolveWorkspace();
|
|
7821
|
+
const key = recordChannelKey(ws, name);
|
|
7822
|
+
runtime.track(key);
|
|
7823
|
+
return runtime.entry(key).status === "running";
|
|
7824
|
+
},
|
|
7825
|
+
status: () => {
|
|
7826
|
+
const ws = runtime.resolveWorkspace();
|
|
7827
|
+
const key = recordChannelKey(ws, name);
|
|
7828
|
+
runtime.track(key);
|
|
7829
|
+
return east.variant(runtime.entry(key).status, null);
|
|
7830
|
+
},
|
|
7831
|
+
error: () => {
|
|
7832
|
+
const ws = runtime.resolveWorkspace();
|
|
7833
|
+
const key = recordChannelKey(ws, name);
|
|
7834
|
+
runtime.track(key);
|
|
7835
|
+
const entry = runtime.entry(key);
|
|
7836
|
+
return entry.status === "failed" && entry.error !== void 0 ? east.some(entry.error) : east.none;
|
|
7837
|
+
},
|
|
7838
|
+
cancel: () => {
|
|
7839
|
+
const ws = runtime.resolveWorkspace();
|
|
7840
|
+
runtime.cancelChannel(recordChannelKey(ws, name), (e3) => {
|
|
7841
|
+
delete e3.error;
|
|
7842
|
+
delete e3.inflight;
|
|
7843
|
+
});
|
|
7844
|
+
return null;
|
|
7845
|
+
}
|
|
7846
|
+
};
|
|
7847
|
+
for (const [mutationName, argTypes] of sig.mutations) {
|
|
7848
|
+
mutate[mutationName] = (...args) => {
|
|
7849
|
+
runtime.launchMutation(runtime.resolveWorkspace(), name, mutationName, argTypes, args);
|
|
7850
|
+
return null;
|
|
7851
|
+
};
|
|
7852
|
+
}
|
|
7853
|
+
return {
|
|
7854
|
+
read: () => {
|
|
7855
|
+
const ws = runtime.resolveWorkspace();
|
|
7856
|
+
trackDatasetPath(ws, path2);
|
|
7857
|
+
const bytes = requireCache().read(ws, path2);
|
|
7858
|
+
if (bytes === void 0) {
|
|
7859
|
+
throw new Error(`Record.bind: record state not loaded: ${datasetCacheKey(ws, path2)} (it should be preloaded via the UI task manifest)`);
|
|
7860
|
+
}
|
|
7861
|
+
return decodeState(bytes);
|
|
7862
|
+
},
|
|
7863
|
+
status: () => {
|
|
7864
|
+
const ws = runtime.resolveWorkspace();
|
|
7865
|
+
trackDatasetPath(ws, path2);
|
|
7866
|
+
return requireCache().getStatus(ws, path2);
|
|
7867
|
+
},
|
|
7868
|
+
history: () => {
|
|
7869
|
+
const ws = runtime.resolveWorkspace();
|
|
7870
|
+
const key = recordChannelKey(ws, name);
|
|
7871
|
+
runtime.track(key);
|
|
7872
|
+
const cached = runtime.histories.get(key);
|
|
7873
|
+
if (cached === void 0) {
|
|
7874
|
+
if (!runtime.historyFailed.has(key)) runtime.fetchHistory(ws, name, key);
|
|
7875
|
+
return east.none;
|
|
7876
|
+
}
|
|
7877
|
+
return east.some(cached);
|
|
7878
|
+
},
|
|
7879
|
+
mutate,
|
|
7880
|
+
start: () => {
|
|
7881
|
+
const ws = runtime.resolveWorkspace();
|
|
7882
|
+
const cache3 = requireCache();
|
|
7883
|
+
const inflight = runtime.entry(recordChannelKey(ws, name)).inflight;
|
|
7884
|
+
void Promise.resolve(inflight).catch(() => void 0).then(() => cache3.launchDataflow(ws)).catch(() => void 0);
|
|
7885
|
+
return null;
|
|
7886
|
+
},
|
|
7887
|
+
binding: { name, mutations: [...sig.mutations.keys()] }
|
|
7888
|
+
};
|
|
7889
|
+
}
|
|
7890
|
+
// ----- platform building -------------------------------------------------
|
|
7891
|
+
/** Build a `Record.bind` PlatformFunction bound to this runtime. Pass
|
|
7892
|
+
* `allowed=null` for an unscoped impl; pass a Set of record names for
|
|
7893
|
+
* manifest scoping. */
|
|
7894
|
+
buildPlatform(allowed) {
|
|
7895
|
+
return internal.recordBindPlatformFn.implement(
|
|
7896
|
+
(handleType) => (nameArg) => {
|
|
7897
|
+
const name = nameArg;
|
|
7898
|
+
if (allowed && !allowed.has(name)) {
|
|
7899
|
+
throw new Error(
|
|
7900
|
+
`Record.bind: record "${name}" is not in this UI task's manifest — bind it in the task body so derivation records it`
|
|
7901
|
+
);
|
|
7902
|
+
}
|
|
7903
|
+
return this.buildHandle(handleType, name);
|
|
7904
|
+
}
|
|
7905
|
+
);
|
|
7906
|
+
}
|
|
7907
|
+
}
|
|
7908
|
+
const defaultRecordRuntime = new RecordRuntime();
|
|
7909
|
+
function initializeRecordApi(api3, cache3, workspace) {
|
|
7910
|
+
defaultRecordRuntime.initialize(api3, cache3, workspace);
|
|
7911
|
+
}
|
|
7912
|
+
function clearRecordApi() {
|
|
7913
|
+
defaultRecordRuntime.clear();
|
|
7914
|
+
}
|
|
7915
|
+
const RecordPlatform = [defaultRecordRuntime.buildPlatform(null)];
|
|
7916
|
+
function createScopedRecordPlatform(records) {
|
|
7917
|
+
return [defaultRecordRuntime.buildPlatform(new Set(records))];
|
|
7918
|
+
}
|
|
7919
|
+
function createInMemoryRecordApi(cache3, workspace, defs2) {
|
|
7920
|
+
const compiled = /* @__PURE__ */ new Map();
|
|
7921
|
+
for (const def of defs2) {
|
|
7922
|
+
const stateType = east.toEastTypeValue(def.stateType);
|
|
7923
|
+
const mutations = /* @__PURE__ */ new Map();
|
|
7924
|
+
for (const m2 of def.mutations) {
|
|
7925
|
+
mutations.set(m2.name, { argTypes: m2.argTypes.map((t4) => east.toEastTypeValue(t4)), reduce: m2.reduce });
|
|
7926
|
+
}
|
|
7927
|
+
const genesis = {
|
|
7928
|
+
hash: `${def.name}-0`.padEnd(64, "0"),
|
|
7929
|
+
parent: east.none,
|
|
7930
|
+
state: `${def.name}-state-0`.padEnd(64, "0"),
|
|
7931
|
+
mutation: "$init",
|
|
7932
|
+
actor: "memory",
|
|
7933
|
+
at: /* @__PURE__ */ new Date(0)
|
|
7934
|
+
};
|
|
7935
|
+
compiled.set(def.name, { stateType, mutations, commits: [genesis], seq: 0 });
|
|
7936
|
+
void cache3.write(workspace, recordPath(def.name), east.encodeBeast2For(stateType)(def.initial));
|
|
7937
|
+
}
|
|
7938
|
+
return {
|
|
7939
|
+
async describe(_ws, record) {
|
|
7940
|
+
const c2 = compiled.get(record);
|
|
7941
|
+
if (!c2) throw new Error(`no in-memory record "${record}"`);
|
|
7942
|
+
return {
|
|
7943
|
+
name: record,
|
|
7944
|
+
mutations: [...c2.mutations].map(([name, m2]) => ({ name, argTypes: m2.argTypes }))
|
|
7945
|
+
};
|
|
7946
|
+
},
|
|
7947
|
+
async mutate(ws, record, mutation, req) {
|
|
7948
|
+
const c2 = compiled.get(record);
|
|
7949
|
+
if (!c2) throw new Error(`no in-memory record "${record}"`);
|
|
7950
|
+
const m2 = c2.mutations.get(mutation);
|
|
7951
|
+
if (!m2) return { outcome: east.variant("invalid", { message: `no mutation "${mutation}"` }) };
|
|
7952
|
+
const current = cache3.read(ws, recordPath(record));
|
|
7953
|
+
const state = current !== void 0 ? east.decodeBeast2For(c2.stateType)(current) : void 0;
|
|
7954
|
+
const args = req.args.map((bytes, i) => east.decodeBeast2For(m2.argTypes[i])(bytes));
|
|
7955
|
+
const next2 = m2.reduce(state, ...args);
|
|
7956
|
+
await cache3.write(ws, recordPath(record), east.encodeBeast2For(c2.stateType)(next2));
|
|
7957
|
+
c2.seq += 1;
|
|
7958
|
+
const hash2 = `${record}-${c2.seq}`.padEnd(64, "0");
|
|
7959
|
+
c2.commits.unshift({
|
|
7960
|
+
hash: hash2,
|
|
7961
|
+
parent: east.some(c2.commits[0].hash),
|
|
7962
|
+
state: `${record}-state-${c2.seq}`.padEnd(64, "0"),
|
|
7963
|
+
mutation,
|
|
7964
|
+
actor: "memory",
|
|
7965
|
+
at: /* @__PURE__ */ new Date(0)
|
|
7966
|
+
});
|
|
7967
|
+
return { outcome: east.variant("committed", { commitHash: hash2, stateHash: `${record}-state-${c2.seq}`.padEnd(64, "0") }) };
|
|
7968
|
+
},
|
|
7969
|
+
async history(_ws, record, limit2) {
|
|
7970
|
+
const c2 = compiled.get(record);
|
|
7971
|
+
if (!c2) throw new Error(`no in-memory record "${record}"`);
|
|
7972
|
+
const commits = limit2 !== void 0 ? c2.commits.slice(0, limit2) : c2.commits;
|
|
7973
|
+
return { commits };
|
|
7974
|
+
}
|
|
7975
|
+
};
|
|
7976
|
+
}
|
|
7977
|
+
platform.registerReactiveTracker({
|
|
7978
|
+
id: "record-bind",
|
|
7979
|
+
enableTracking: () => defaultRecordRuntime.enableTracking(),
|
|
7980
|
+
disableTracking: () => defaultRecordRuntime.disableTracking(),
|
|
7981
|
+
getStore: () => ({
|
|
7982
|
+
subscribe: (key, cb) => defaultRecordRuntime.subscribe(key, cb),
|
|
7983
|
+
getKeyVersion: (key) => defaultRecordRuntime.getKeyVersion(key)
|
|
7984
|
+
})
|
|
7985
|
+
});
|
|
7986
|
+
platform.registerPlatformImplementation(RecordPlatform);
|
|
7472
7987
|
const E3ConfigContext = React.createContext(null);
|
|
7473
7988
|
function E3Provider({ children: children2, config: config2, queryClient: externalClient }) {
|
|
7474
7989
|
const client = React.useMemo(
|
|
@@ -7519,11 +8034,21 @@ function ReactiveDatasetProvider({
|
|
|
7519
8034
|
);
|
|
7520
8035
|
}
|
|
7521
8036
|
}, [e3.apiUrl, e3.repo, e3.workspace]);
|
|
8037
|
+
React.useMemo(() => {
|
|
8038
|
+
if (e3.workspace !== void 0) {
|
|
8039
|
+
initializeRecordApi(
|
|
8040
|
+
createDefaultRecordApi(e3.apiUrl, e3.repo ?? "default", () => tokenRef.current),
|
|
8041
|
+
cache3,
|
|
8042
|
+
e3.workspace
|
|
8043
|
+
);
|
|
8044
|
+
}
|
|
8045
|
+
}, [e3.apiUrl, e3.repo, e3.workspace, cache3]);
|
|
7522
8046
|
React.useEffect(() => {
|
|
7523
8047
|
return () => {
|
|
7524
8048
|
const ws = cache3.getConfig().workspace;
|
|
7525
8049
|
clearReactiveDatasetCache();
|
|
7526
8050
|
clearFunctionApi();
|
|
8051
|
+
clearRecordApi();
|
|
7527
8052
|
cache3.destroy();
|
|
7528
8053
|
if (ws) clearBindingRegistry(ws);
|
|
7529
8054
|
else clearBindingRegistry();
|
|
@@ -60731,30 +61256,37 @@ function RefusalZone({ refusal, overlap, naiveValue, outcome }) {
|
|
|
60731
61256
|
] });
|
|
60732
61257
|
}
|
|
60733
61258
|
function ValidatePanel({ vm, barList }) {
|
|
60734
|
-
const
|
|
61259
|
+
const stat = react.useSlotRecipe({ key: "stat" })({ size: "lg" });
|
|
61260
|
+
const meter = react.useSlotRecipe({ key: "segmentedMeter" })({});
|
|
60735
61261
|
return /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { p: "4.5", children: [
|
|
60736
61262
|
/* @__PURE__ */ jsxRuntime.jsx(Cap, { help: "tab_validate", children: vm.headline }),
|
|
60737
61263
|
/* @__PURE__ */ jsxRuntime.jsxs(react.Box, { display: "flex", alignItems: "flex-end", gap: "5", flexWrap: "wrap", children: [
|
|
60738
|
-
/* @__PURE__ */ jsxRuntime.jsxs(react.Box, {
|
|
60739
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.Text, {
|
|
60740
|
-
vm.faint ? /* @__PURE__ */ jsxRuntime.jsx(react.Text, { textStyle: "body.sm", fontWeight: "semibold", color: "fg.warning", maxW: "220px", children: "Effect too faint to size — set a materiality threshold to size a trial." }) : /* @__PURE__ */ jsxRuntime.jsx(react.Text, {
|
|
61264
|
+
/* @__PURE__ */ jsxRuntime.jsxs(react.Box, { css: stat.root, children: [
|
|
61265
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Text, { css: stat.label, children: /* @__PURE__ */ jsxRuntime.jsx(Help, { id: "validate_size", children: vm.holdback ? "to hold back from" : "to run" }) }),
|
|
61266
|
+
vm.faint ? /* @__PURE__ */ jsxRuntime.jsx(react.Text, { textStyle: "body.sm", fontWeight: "semibold", color: "fg.warning", maxW: "220px", children: "Effect too faint to size — set a materiality threshold to size a trial." }) : /* @__PURE__ */ jsxRuntime.jsx(react.Text, { css: stat.valueText, color: "brand.solid", children: vm.primary.nTotal.toLocaleString() })
|
|
60741
61267
|
] }),
|
|
60742
|
-
/* @__PURE__ */ jsxRuntime.jsxs(react.Box, { flex: "1", minW: "220px", children: [
|
|
60743
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
60744
|
-
/* @__PURE__ */ jsxRuntime.jsxs(react.Box, {
|
|
60745
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.Box, { bg: "brand.solid"
|
|
60746
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.Box, {
|
|
61268
|
+
/* @__PURE__ */ jsxRuntime.jsxs(react.Box, { css: meter.root, flex: "1", minW: "220px", children: [
|
|
61269
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Text, { css: meter.label, children: /* @__PURE__ */ jsxRuntime.jsx(Help, { id: "validate_split", children: vm.holdback ? "Hold-back split" : "Split" }) }),
|
|
61270
|
+
/* @__PURE__ */ jsxRuntime.jsxs(react.Box, { css: meter.track, children: [
|
|
61271
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Box, { css: meter.segment, flex: vm.primary.treatedShare, bg: "brand.solid" }),
|
|
61272
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Box, { css: meter.segment, flex: 1 - vm.primary.treatedShare, bg: "bg.emphasized" })
|
|
60747
61273
|
] }),
|
|
60748
|
-
/* @__PURE__ */ jsxRuntime.jsxs(react.Box, {
|
|
60749
|
-
/* @__PURE__ */ jsxRuntime.jsxs(react.
|
|
60750
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.
|
|
60751
|
-
|
|
60752
|
-
|
|
61274
|
+
/* @__PURE__ */ jsxRuntime.jsxs(react.Box, { css: meter.keyRow, justifyContent: "space-between", children: [
|
|
61275
|
+
/* @__PURE__ */ jsxRuntime.jsxs(react.Box, { css: meter.keyItem, children: [
|
|
61276
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Box, { css: meter.keyDot, bg: "brand.solid" }),
|
|
61277
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
61278
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Text, { as: "span", css: meter.valueText, children: vm.primary.nTreated.toLocaleString() }),
|
|
61279
|
+
" ",
|
|
61280
|
+
vm.holdback ? "treated" : "get it"
|
|
61281
|
+
] })
|
|
60753
61282
|
] }),
|
|
60754
|
-
/* @__PURE__ */ jsxRuntime.jsxs(react.
|
|
60755
|
-
/* @__PURE__ */ jsxRuntime.jsx(react.
|
|
60756
|
-
|
|
60757
|
-
|
|
61283
|
+
/* @__PURE__ */ jsxRuntime.jsxs(react.Box, { css: meter.keyItem, children: [
|
|
61284
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Box, { css: meter.keyDot, bg: "bg.emphasized" }),
|
|
61285
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
61286
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Text, { as: "span", css: meter.valueText, children: vm.primary.nControl.toLocaleString() }),
|
|
61287
|
+
" ",
|
|
61288
|
+
vm.holdback ? "held back" : "left alone"
|
|
61289
|
+
] })
|
|
60758
61290
|
] })
|
|
60759
61291
|
] })
|
|
60760
61292
|
] })
|
|
@@ -63046,7 +63578,7 @@ const UITaskPreview = React.memo(function UITaskPreview2({
|
|
|
63046
63578
|
const manifest = React.useMemo(() => {
|
|
63047
63579
|
if (!details || !isUI) return null;
|
|
63048
63580
|
const meta3 = getTaskMetadata(details);
|
|
63049
|
-
return meta3 ? internal.decodeManifest(meta3) : { paths: [], functions: [] };
|
|
63581
|
+
return meta3 ? internal.decodeManifest(meta3) : { paths: [], functions: [], records: [] };
|
|
63050
63582
|
}, [details, isUI]);
|
|
63051
63583
|
const outputPath = details ? treePathToString$1(details.output) : null;
|
|
63052
63584
|
const preloads = React.useMemo(
|
|
@@ -63059,6 +63591,7 @@ const UITaskPreview = React.memo(function UITaskPreview2({
|
|
|
63059
63591
|
...eastUiComponents.StateImpl,
|
|
63060
63592
|
...createScopedBindPlatform(manifest),
|
|
63061
63593
|
...createScopedFuncPlatform(manifest.functions),
|
|
63594
|
+
...createScopedRecordPlatform(manifest.records),
|
|
63062
63595
|
...eastUiComponents.OverlayImpl
|
|
63063
63596
|
] : void 0,
|
|
63064
63597
|
[manifest]
|
|
@@ -63656,6 +64189,8 @@ exports.MemoryStagedAdapter = MemoryStagedAdapter;
|
|
|
63656
64189
|
exports.ReactiveDatasetCache = ReactiveDatasetCache;
|
|
63657
64190
|
exports.ReactiveDatasetLoader = ReactiveDatasetLoader;
|
|
63658
64191
|
exports.ReactiveDatasetProvider = ReactiveDatasetProvider;
|
|
64192
|
+
exports.RecordPlatform = RecordPlatform;
|
|
64193
|
+
exports.RecordRuntime = RecordRuntime;
|
|
63659
64194
|
exports.StagedStore = StagedStore;
|
|
63660
64195
|
exports.StatusDisplay = StatusDisplay;
|
|
63661
64196
|
exports.TaskPreview = TaskPreview;
|
|
@@ -63667,17 +64202,22 @@ exports.clearFunctionApi = clearFunctionApi;
|
|
|
63667
64202
|
exports.clearPendingWrites = clearPendingWrites;
|
|
63668
64203
|
exports.clearReactiveDatasetCache = clearReactiveDatasetCache;
|
|
63669
64204
|
exports.clearReactiveDatasetListCache = clearReactiveDatasetListCache;
|
|
64205
|
+
exports.clearRecordApi = clearRecordApi;
|
|
63670
64206
|
exports.clearStagedStoreSingleton = clearStagedStoreSingleton;
|
|
63671
64207
|
exports.createDefaultDatasetApi = createDefaultDatasetApi;
|
|
63672
64208
|
exports.createDefaultFunctionApi = createDefaultFunctionApi;
|
|
64209
|
+
exports.createDefaultRecordApi = createDefaultRecordApi;
|
|
63673
64210
|
exports.createInMemoryFunctionApi = createInMemoryFunctionApi;
|
|
64211
|
+
exports.createInMemoryRecordApi = createInMemoryRecordApi;
|
|
63674
64212
|
exports.createReactiveDatasetCache = createReactiveDatasetCache;
|
|
63675
64213
|
exports.createScopedBindPlatform = createScopedBindPlatform;
|
|
63676
64214
|
exports.createScopedFuncPlatform = createScopedFuncPlatform;
|
|
64215
|
+
exports.createScopedRecordPlatform = createScopedRecordPlatform;
|
|
63677
64216
|
exports.datasetCacheKey = datasetCacheKey;
|
|
63678
64217
|
exports.datasetPathToString = datasetPathToString;
|
|
63679
64218
|
exports.defaultBindRuntime = defaultBindRuntime;
|
|
63680
64219
|
exports.defaultFuncRuntime = defaultFuncRuntime;
|
|
64220
|
+
exports.defaultRecordRuntime = defaultRecordRuntime;
|
|
63681
64221
|
exports.disableBindingTracking = disableBindingTracking;
|
|
63682
64222
|
exports.enableBindingTracking = enableBindingTracking;
|
|
63683
64223
|
exports.formatApiError = formatApiError;
|
|
@@ -63690,12 +64230,14 @@ exports.getTaskKind = getTaskKind;
|
|
|
63690
64230
|
exports.getTaskMetadata = getTaskMetadata;
|
|
63691
64231
|
exports.initializeFunctionApi = initializeFunctionApi;
|
|
63692
64232
|
exports.initializeReactiveDatasetCache = initializeReactiveDatasetCache;
|
|
64233
|
+
exports.initializeRecordApi = initializeRecordApi;
|
|
63693
64234
|
exports.initializeStagedStore = initializeStagedStore;
|
|
63694
64235
|
exports.isBindingTracking = isBindingTracking;
|
|
63695
64236
|
exports.onWriteError = onWriteError;
|
|
63696
64237
|
exports.preloadReactiveDatasetList = preloadReactiveDatasetList;
|
|
63697
64238
|
exports.realClock = realClock;
|
|
63698
|
-
exports.
|
|
64239
|
+
exports.recordChannelKey = recordChannelKey;
|
|
64240
|
+
exports.signatureOfFuncHandleType = signatureOfFuncHandleType;
|
|
63699
64241
|
exports.trackDatasetPath = trackDatasetPath;
|
|
63700
64242
|
exports.useDataflowCancel = useDataflowCancel;
|
|
63701
64243
|
exports.useDataflowExecute = useDataflowExecute;
|