@elaraai/e3-ui-components 1.0.25 → 1.0.27

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.cjs CHANGED
@@ -21,9 +21,10 @@ var __privateWrapper = (obj, member, setter, getter) => ({
21
21
  var _focused, _cleanup, _setup, _a, _provider, _providerCalled, _b, _online, _cleanup2, _setup2, _c, _gcTimeout, _d, _initialState, _revertState, _cache, _client, _retryer, _defaultOptions, _abortSignalConsumed, _Query_instances, isInitialPausedFetch_fn, dispatch_fn, _e, _client2, _observers, _mutationCache, _retryer2, _Mutation_instances, dispatch_fn2, _f, _mutations, _scopes, _mutationId, _g, _queries, _h, _queryCache, _mutationCache2, _defaultOptions2, _queryDefaults, _mutationDefaults, _mountCount, _unsubscribeFocus, _unsubscribeOnline, _i, _j;
22
22
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
23
23
  const east = require("@elaraai/east");
24
- const internal$1 = require("@elaraai/east/internal");
25
- const internal = require("@elaraai/e3-ui/internal");
24
+ const internal = require("@elaraai/east/internal");
25
+ const internal$1 = require("@elaraai/e3-ui/internal");
26
26
  const platform = require("@elaraai/east-ui-components/platform");
27
+ const e3Types = require("@elaraai/e3-types");
27
28
  const e3ApiClient = require("@elaraai/e3-api-client");
28
29
  const jsxRuntime = require("react/jsx-runtime");
29
30
  const React = require("react");
@@ -2312,6 +2313,11 @@ class ReactiveDatasetCache {
2312
2313
  });
2313
2314
  } catch (error3) {
2314
2315
  if (isCancelledError(error3)) return;
2316
+ if (isDatasetUnassignedError(error3)) {
2317
+ this.statuses.set(key, east.variant("unset", null));
2318
+ this.notifyChange(key);
2319
+ return;
2320
+ }
2315
2321
  throw error3;
2316
2322
  }
2317
2323
  if (this.destroyed) {
@@ -2609,6 +2615,9 @@ class ReactiveDatasetCache {
2609
2615
  function isCancelledError(error3) {
2610
2616
  return error3 instanceof CancelledError;
2611
2617
  }
2618
+ function isDatasetUnassignedError(error3) {
2619
+ return error3 instanceof e3ApiClient.ApiError && error3.code === "dataset_unassigned";
2620
+ }
2612
2621
  function createReactiveDatasetCache(config2, api3, clock2) {
2613
2622
  return new ReactiveDatasetCache(config2, api3, clock2);
2614
2623
  }
@@ -2874,10 +2883,10 @@ function clearStagedStoreSingleton() {
2874
2883
  }
2875
2884
  const UNCHANGED_VARIANT = east.variant("unchanged", null);
2876
2885
  const blobEqual = east.equalFor(east.BlobType);
2877
- const eastTypeEqual$2 = east.equalFor(internal$1.EastTypeType);
2886
+ const eastTypeEqual$2 = east.equalFor(internal.EastTypeType);
2878
2887
  const helpersCache = new east.SortedMap(
2879
2888
  void 0,
2880
- east.compareFor(internal$1.EastTypeType)
2889
+ east.compareFor(internal.EastTypeType)
2881
2890
  );
2882
2891
  function getBindingHelpers(sourceType) {
2883
2892
  let cached = helpersCache.get(sourceType);
@@ -2926,6 +2935,17 @@ class BindRuntime {
2926
2935
  __publicField(this, "fallbackWarningEmitted", /* @__PURE__ */ new Set());
2927
2936
  // List cache helpers.
2928
2937
  __publicField(this, "listCache", /* @__PURE__ */ new Map());
2938
+ // Compiled-handle cache (issue #106 perf). The bind impl compiles N
2939
+ // East.function methods per bind, and binds re-run on every reactive frame.
2940
+ // The compiled IR is a pure function of (sourceType, sourcePath, patch, mode)
2941
+ // — same key ⇒ same methods — and the methods resolve cache/workspace LIVE,
2942
+ // so a cached handle still re-binds correctly across renders / cache swaps.
2943
+ // Keyed *structurally* (each bind builds a fresh EastTypeValue from IR, so a
2944
+ // by-identity cache would miss every render — same reason as helpersCache).
2945
+ __publicField(this, "handleCache", new east.SortedMap(
2946
+ void 0,
2947
+ east.compareFor(internal.EastTypeType)
2948
+ ));
2929
2949
  this.staged = staged;
2930
2950
  this.staged.onPersistError((_key, err) => this.emitWriteError(err));
2931
2951
  }
@@ -2956,6 +2976,7 @@ class BindRuntime {
2956
2976
  clearCache() {
2957
2977
  this.cache = null;
2958
2978
  this.clearPendingWrites();
2979
+ this.handleCache.clear();
2959
2980
  }
2960
2981
  // ----- pending writes queue -------------------------------------------
2961
2982
  /** Subscribe to write-queue errors. Returns an unsubscribe fn. */
@@ -3082,13 +3103,14 @@ class BindRuntime {
3082
3103
  }
3083
3104
  // ----- bind-handle construction --------------------------------------
3084
3105
  /**
3085
- * Build a bind handle for a single `(sourcePath, mode, patch?)`
3086
- * triple. Public so tests can call this directly without going
3087
- * through East's compile/dispatch pipeline.
3106
+ * Build a `Data.bind` handle. Its methods are thin IR-bearing
3107
+ * `East.function`s over the `data_*` primitives, capturing only the
3108
+ * plain-data `{source, patch, mode}` descriptor — so the handle is ordinary
3109
+ * serializable East data (issue #106) and re-binds to the decoder's cache.
3110
+ * Public so tests can call it directly without East's compile/dispatch.
3088
3111
  *
3089
- * @throws `EastError` if the cache is uninitialized, the
3090
- * workspace is not configured, or `allowed` is non-null and any
3091
- * referenced path is not in it.
3112
+ * @throws `EastError` if the cache is uninitialized, the workspace is not
3113
+ * configured, or `allowed` is non-null and any referenced path is not in it.
3092
3114
  */
3093
3115
  buildBindHandle(sourceType, sourcePath, patchPath, mode, allowed) {
3094
3116
  const cache3 = this.requireCache();
@@ -3112,6 +3134,106 @@ class BindRuntime {
3112
3134
  }
3113
3135
  }
3114
3136
  }
3137
+ const { patchType } = getBindingHelpers(sourceType);
3138
+ this.registerBindingTypes(ws, sourcePath, {
3139
+ workspace: ws,
3140
+ sourceType,
3141
+ patchType,
3142
+ mode,
3143
+ hasPatchDataset: patchPath !== void 0
3144
+ });
3145
+ const descKey = `${datasetPathToString(sourcePath)}\0${patchPath !== void 0 ? datasetPathToString(patchPath) : ""}\0${mode}`;
3146
+ let byDesc = this.handleCache.get(sourceType);
3147
+ if (byDesc) {
3148
+ const hit = byDesc.get(descKey);
3149
+ if (hit) return hit;
3150
+ } else {
3151
+ byDesc = /* @__PURE__ */ new Map();
3152
+ this.handleCache.set(sourceType, byDesc);
3153
+ }
3154
+ const T2 = east.fromEastTypeValue(sourceType);
3155
+ const srcExpr = east.East.value(sourcePath, e3Types.TreePathType);
3156
+ const patchExpr = east.East.value(patchPath !== void 0 ? east.some(patchPath) : east.none, east.OptionType(e3Types.TreePathType));
3157
+ const modeExpr = east.East.value(east.variant(mode, null), internal$1.DataBindModeType);
3158
+ const platform2 = this.buildPrimitives();
3159
+ const P2 = internal$1.DataBindPrimitives;
3160
+ const handle = {
3161
+ read: east.East.compile(east.East.function([], T2, ($3) => {
3162
+ $3.return(P2.read([T2], srcExpr, patchExpr, modeExpr));
3163
+ }), platform2),
3164
+ write: east.East.compile(east.East.function([T2], east.NullType, ($3, v3) => {
3165
+ $3.return(P2.write([T2], srcExpr, patchExpr, modeExpr, v3));
3166
+ }), platform2),
3167
+ writeAndStart: east.East.compile(east.East.function([T2], east.NullType, ($3, v3) => {
3168
+ $3.return(P2.writeAndStart([T2], srcExpr, patchExpr, modeExpr, v3));
3169
+ }), platform2),
3170
+ start: east.East.compile(east.East.function([], east.NullType, ($3) => {
3171
+ $3.return(P2.start([T2], srcExpr, patchExpr, modeExpr));
3172
+ }), platform2),
3173
+ source: east.East.compile(east.East.function([], T2, ($3) => {
3174
+ $3.return(P2.source([T2], srcExpr, patchExpr, modeExpr));
3175
+ }), platform2),
3176
+ pending: east.East.compile(east.East.function([], east.BooleanType, ($3) => {
3177
+ $3.return(P2.pending([T2], srcExpr, patchExpr, modeExpr));
3178
+ }), platform2),
3179
+ commit: east.East.compile(east.East.function([], east.NullType, ($3) => {
3180
+ $3.return(P2.commit([T2], srcExpr, patchExpr, modeExpr));
3181
+ }), platform2),
3182
+ discard: east.East.compile(east.East.function([], east.NullType, ($3) => {
3183
+ $3.return(P2.discard([T2], srcExpr, patchExpr, modeExpr));
3184
+ }), platform2),
3185
+ has: east.East.compile(east.East.function([], east.BooleanType, ($3) => {
3186
+ $3.return(P2.has([T2], srcExpr, patchExpr, modeExpr));
3187
+ }), platform2),
3188
+ status: east.East.compile(east.East.function([], e3Types.DatasetStatusType, ($3) => {
3189
+ $3.return(P2.status([T2], srcExpr, patchExpr, modeExpr));
3190
+ }), platform2),
3191
+ binding: {
3192
+ source: sourcePath,
3193
+ patch: patchPath !== void 0 ? east.some(patchPath) : east.none,
3194
+ mode: east.variant(mode, null)
3195
+ }
3196
+ };
3197
+ byDesc.set(descKey, handle);
3198
+ return handle;
3199
+ }
3200
+ /**
3201
+ * The low-level primitives backing handle methods, bound to THIS runtime.
3202
+ * Registered globally (extension registry) and included by the scoped
3203
+ * platform (e3 `ui()` tasks) so a decoded handle re-binds here. Each impl
3204
+ * recovers the `{source, patch, mode}` descriptor from its args and delegates
3205
+ * to {@link buildRawHandle}, reusing the full mode×patch logic verbatim.
3206
+ */
3207
+ buildPrimitives() {
3208
+ const raw = (sourceType, sourceArg, patchOpt, modeVariant) => {
3209
+ const { patchPath, mode } = resolveOptions(patchOpt, modeVariant);
3210
+ return this.buildRawHandle(sourceType, sourceArg, patchPath, mode);
3211
+ };
3212
+ const P2 = internal$1.DataBindPrimitives;
3213
+ return [
3214
+ P2.read.implement((t4) => (s2, p2, m2) => raw(t4, s2, p2, m2).read()),
3215
+ P2.source.implement((t4) => (s2, p2, m2) => raw(t4, s2, p2, m2).source()),
3216
+ P2.write.implement((t4) => (s2, p2, m2, v3) => raw(t4, s2, p2, m2).write(v3)),
3217
+ P2.writeAndStart.implement((t4) => (s2, p2, m2, v3) => raw(t4, s2, p2, m2).writeAndStart(v3)),
3218
+ P2.start.implement((t4) => (s2, p2, m2) => raw(t4, s2, p2, m2).start()),
3219
+ P2.pending.implement((t4) => (s2, p2, m2) => raw(t4, s2, p2, m2).pending()),
3220
+ P2.commit.implement((t4) => (s2, p2, m2) => raw(t4, s2, p2, m2).commit()),
3221
+ P2.discard.implement((t4) => (s2, p2, m2) => raw(t4, s2, p2, m2).discard()),
3222
+ P2.has.implement((t4) => (s2, p2, m2) => raw(t4, s2, p2, m2).has()),
3223
+ P2.status.implement((t4) => (s2, p2, m2) => raw(t4, s2, p2, m2).status())
3224
+ ];
3225
+ }
3226
+ /**
3227
+ * Build the raw (host-closure) bind handle for a single
3228
+ * `(sourcePath, mode, patch?)` triple. The mode×patch matrix lives here; the
3229
+ * serializable {@link buildBindHandle} wraps each method as an `East.function`
3230
+ * over a primitive that delegates back here. Re-registers binding types on
3231
+ * every call (decode self-heal). Public so tests can drive the raw closures.
3232
+ */
3233
+ buildRawHandle(sourceType, sourcePath, patchPath, mode) {
3234
+ const cache3 = this.requireCache();
3235
+ const ws = cache3.getConfig().workspace;
3236
+ if (!ws) throw new Error("ReactiveDatasetCache workspace not configured");
3115
3237
  const { patchType, decodeT, encodeT, decodePatch, encodePatch, apply: apply2, diff: diff2 } = getBindingHelpers(sourceType);
3116
3238
  this.registerBindingTypes(ws, sourcePath, {
3117
3239
  workspace: ws,
@@ -3351,7 +3473,7 @@ class BindRuntime {
3351
3473
  * Pass `allowed=null` for an unscoped impl (the global
3352
3474
  * `BindPlatform`); pass a Set for manifest scoping. */
3353
3475
  buildPlatform(allowed) {
3354
- return internal.bindPlatformFn.implement(
3476
+ return internal$1.bindPlatformFn.implement(
3355
3477
  (sourceType) => (sourcePathArg, patchOpt, modeVariant) => {
3356
3478
  const sourcePath = sourcePathArg;
3357
3479
  const { patchPath, mode } = resolveOptions(patchOpt, modeVariant);
@@ -3426,10 +3548,16 @@ function awaitPendingWrites() {
3426
3548
  function clearPendingWrites() {
3427
3549
  defaultBindRuntime.clearPendingWrites();
3428
3550
  }
3429
- const BindPlatform = [defaultBindRuntime.buildPlatform(null)];
3551
+ const BindPlatform = [
3552
+ defaultBindRuntime.buildPlatform(null),
3553
+ ...defaultBindRuntime.buildPrimitives()
3554
+ ];
3430
3555
  function createScopedBindPlatform(manifest) {
3431
3556
  const allowed = new Set(manifest.paths.map((p2) => datasetPathToString(p2)));
3432
- return [defaultBindRuntime.buildPlatform(allowed)];
3557
+ return [
3558
+ defaultBindRuntime.buildPlatform(allowed),
3559
+ ...defaultBindRuntime.buildPrimitives()
3560
+ ];
3433
3561
  }
3434
3562
  async function preloadReactiveDatasetList(workspace, path2) {
3435
3563
  return defaultBindRuntime.preloadList(workspace, path2);
@@ -3578,7 +3706,7 @@ function createDefaultFunctionApi(apiUrl, repo, getToken) {
3578
3706
  }
3579
3707
  };
3580
3708
  }
3581
- const eastTypeEqual$1 = east.equalFor(internal$1.EastTypeType);
3709
+ const eastTypeEqual$1 = east.equalFor(internal.EastTypeType);
3582
3710
  function signatureOfFuncHandleType(handleType) {
3583
3711
  var _a2, _b2;
3584
3712
  if (handleType.type !== "Struct") {
@@ -3659,6 +3787,11 @@ class FuncRuntime extends TrackedChannelStore {
3659
3787
  __publicField(this, "workspace", null);
3660
3788
  // Signature lists are fetched once per workspace and cached.
3661
3789
  __publicField(this, "signatureLists", /* @__PURE__ */ new Map());
3790
+ // Compiled-handle cache (issue #106 perf): buildHandle compiles 6 East.functions
3791
+ // per bind, and binds re-run every reactive frame. The method IR is a pure
3792
+ // function of the function name (which fixes the handle type), and the methods
3793
+ // resolve workspace/api LIVE, so a cached handle still re-binds. Cleared on clear().
3794
+ __publicField(this, "handleCache", /* @__PURE__ */ new Map());
3662
3795
  }
3663
3796
  createEntry() {
3664
3797
  return { status: "idle", launchSeq: 0 };
@@ -3676,6 +3809,7 @@ class FuncRuntime extends TrackedChannelStore {
3676
3809
  this.workspace = null;
3677
3810
  this.clearChannels();
3678
3811
  this.signatureLists.clear();
3812
+ this.handleCache.clear();
3679
3813
  }
3680
3814
  /** The deployed signature list for a workspace (fetched once). */
3681
3815
  signatures(workspace) {
@@ -3779,9 +3913,15 @@ class FuncRuntime extends TrackedChannelStore {
3779
3913
  }
3780
3914
  })();
3781
3915
  }
3782
- /** Build the handle value for one `Func.bind` platform evaluation. */
3783
- buildHandle(handleType, name) {
3784
- const sig = signatureOfFuncHandleType(handleType);
3916
+ /**
3917
+ * The 6 low-level primitives backing handle methods, bound to THIS runtime.
3918
+ * Registered globally (extension registry) and included by the scoped
3919
+ * platform (e3 `ui()` tasks) so a decoded handle re-binds to whatever runtime
3920
+ * resolves the primitives on the decode side. The host effects (launch /
3921
+ * channel reads + reactive tracking) live here, keyed only on the plain-data
3922
+ * function name; the output type rides as a type-arg.
3923
+ */
3924
+ buildPrimitives() {
3785
3925
  const runtime = this;
3786
3926
  const resolveWorkspace = () => {
3787
3927
  if (!runtime.workspace) {
@@ -3789,49 +3929,98 @@ class FuncRuntime extends TrackedChannelStore {
3789
3929
  }
3790
3930
  return runtime.workspace;
3791
3931
  };
3792
- const channel = () => {
3932
+ const channel = (name) => {
3793
3933
  const key = funcChannelKey(resolveWorkspace(), name);
3794
3934
  return { key, entry: runtime.entry(key) };
3795
3935
  };
3796
- return {
3797
- call: (...args) => {
3798
- runtime.launch(resolveWorkspace(), name, sig, args);
3936
+ return [
3937
+ // call: recover per-arg input types from the ArgsStruct type-arg + the
3938
+ // values from the passed struct (field order), and the output type from O.
3939
+ internal$1.FuncBindPrimitives.call.implement((argsStructType, outputType) => (nameArg, argsStruct) => {
3940
+ const fields = argsStructType.value;
3941
+ const obj = argsStruct;
3942
+ const inputs = fields.map((f2) => f2.type);
3943
+ const args = fields.map((f2) => obj[f2.name]);
3944
+ runtime.launch(resolveWorkspace(), nameArg, { inputs, output: outputType }, args);
3799
3945
  return null;
3800
- },
3801
- read: () => {
3802
- const { key, entry } = channel();
3946
+ }),
3947
+ internal$1.FuncBindPrimitives.read.implement((_outputType) => (nameArg) => {
3948
+ const { key, entry } = channel(nameArg);
3803
3949
  runtime.track(key);
3804
3950
  return entry.result !== void 0 ? east.variant("some", entry.result) : east.variant("none", null);
3805
- },
3806
- status: () => {
3807
- const { key, entry } = channel();
3951
+ }),
3952
+ internal$1.FuncBindPrimitives.status.implement((nameArg) => {
3953
+ const { key, entry } = channel(nameArg);
3808
3954
  runtime.track(key);
3809
3955
  return east.variant(entry.status, null);
3810
- },
3811
- error: () => {
3812
- const { key, entry } = channel();
3956
+ }),
3957
+ internal$1.FuncBindPrimitives.error.implement((nameArg) => {
3958
+ const { key, entry } = channel(nameArg);
3813
3959
  runtime.track(key);
3814
3960
  return entry.status === "failed" && entry.error !== void 0 ? east.variant("some", entry.error) : east.variant("none", null);
3815
- },
3816
- pending: () => {
3817
- const { key, entry } = channel();
3961
+ }),
3962
+ internal$1.FuncBindPrimitives.pending.implement((nameArg) => {
3963
+ const { key, entry } = channel(nameArg);
3818
3964
  runtime.track(key);
3819
3965
  return entry.status === "running";
3820
- },
3821
- cancel: () => {
3822
- const { key } = channel();
3966
+ }),
3967
+ internal$1.FuncBindPrimitives.cancel.implement((nameArg) => {
3968
+ const { key } = channel(nameArg);
3823
3969
  runtime.cancelChannel(key);
3824
3970
  return null;
3825
- },
3971
+ })
3972
+ ];
3973
+ }
3974
+ /**
3975
+ * Build the handle value for one `Func.bind` evaluation. The methods are
3976
+ * thin IR-bearing `East.function`s over {@link buildPrimitives}, capturing
3977
+ * only the function name (and the signature types via type-args) — so the
3978
+ * handle is ordinary serializable East data (issue #106).
3979
+ */
3980
+ buildHandle(handleType, name) {
3981
+ const cached = this.handleCache.get(name);
3982
+ if (cached) return cached;
3983
+ const sig = signatureOfFuncHandleType(handleType);
3984
+ const inputsEast = sig.inputs.map((t4) => east.fromEastTypeValue(t4));
3985
+ const outputEast = east.fromEastTypeValue(sig.output);
3986
+ const ArgsStruct = east.StructType(Object.fromEntries(inputsEast.map((t4, i) => [`arg${i}`, t4])));
3987
+ const nameExpr = east.East.value(name, east.StringType);
3988
+ const platform2 = this.buildPrimitives();
3989
+ const { call, read, status, error: error3, pending, cancel } = internal$1.FuncBindPrimitives;
3990
+ const handle = {
3991
+ call: east.East.compile(east.East.function(inputsEast, east.NullType, ($3, ...args) => {
3992
+ const obj = {};
3993
+ args.forEach((a2, i) => {
3994
+ obj[`arg${i}`] = a2;
3995
+ });
3996
+ $3.return(call([ArgsStruct, outputEast], nameExpr, east.East.value(obj, ArgsStruct)));
3997
+ }), platform2),
3998
+ read: east.East.compile(east.East.function([], east.OptionType(outputEast), ($3) => {
3999
+ $3.return(read([outputEast], nameExpr));
4000
+ }), platform2),
4001
+ status: east.East.compile(east.East.function([], internal$1.FuncStatusType, ($3) => {
4002
+ $3.return(status(nameExpr));
4003
+ }), platform2),
4004
+ error: east.East.compile(east.East.function([], east.OptionType(internal$1.FuncErrorType), ($3) => {
4005
+ $3.return(error3(nameExpr));
4006
+ }), platform2),
4007
+ pending: east.East.compile(east.East.function([], east.BooleanType, ($3) => {
4008
+ $3.return(pending(nameExpr));
4009
+ }), platform2),
4010
+ cancel: east.East.compile(east.East.function([], east.NullType, ($3) => {
4011
+ $3.return(cancel(nameExpr));
4012
+ }), platform2),
3826
4013
  binding: { name }
3827
4014
  };
4015
+ this.handleCache.set(name, handle);
4016
+ return handle;
3828
4017
  }
3829
4018
  // ----- platform building -------------------------------------------------
3830
4019
  /** Build a `Func.bind` PlatformFunction bound to this runtime. Pass
3831
4020
  * `allowed=null` for an unscoped impl; pass a Set of function names
3832
4021
  * for manifest scoping. */
3833
4022
  buildPlatform(allowed) {
3834
- return internal.funcBindPlatformFn.implement(
4023
+ return internal$1.funcBindPlatformFn.implement(
3835
4024
  (handleType) => (nameArg) => {
3836
4025
  const name = nameArg;
3837
4026
  if (allowed && !allowed.has(name)) {
@@ -3851,9 +4040,15 @@ function initializeFunctionApi(api3, workspace) {
3851
4040
  function clearFunctionApi() {
3852
4041
  defaultFuncRuntime.clear();
3853
4042
  }
3854
- const FuncPlatform = [defaultFuncRuntime.buildPlatform(null)];
4043
+ const FuncPlatform = [
4044
+ defaultFuncRuntime.buildPlatform(null),
4045
+ ...defaultFuncRuntime.buildPrimitives()
4046
+ ];
3855
4047
  function createScopedFuncPlatform(functions2) {
3856
- return [defaultFuncRuntime.buildPlatform(new Set(functions2))];
4048
+ return [
4049
+ defaultFuncRuntime.buildPlatform(new Set(functions2)),
4050
+ ...defaultFuncRuntime.buildPrimitives()
4051
+ ];
3857
4052
  }
3858
4053
  function createInMemoryFunctionApi(functions2) {
3859
4054
  const defs2 = functions2.map((def) => ({
@@ -7578,7 +7773,7 @@ function createDefaultRecordApi(apiUrl, repo, getToken) {
7578
7773
  }
7579
7774
  };
7580
7775
  }
7581
- const eastTypeEqual = east.equalFor(internal$1.EastTypeType);
7776
+ const eastTypeEqual = east.equalFor(internal.EastTypeType);
7582
7777
  const RESERVED_MUTATE_FIELDS = /* @__PURE__ */ new Set(["pending", "status", "error", "cancel"]);
7583
7778
  function signatureOfRecordHandleType(handleType) {
7584
7779
  var _a2, _b2;
@@ -7663,6 +7858,12 @@ class RecordRuntime extends TrackedChannelStore {
7663
7858
  // otherwise spin); cleared on the next commit / on clear() so a later
7664
7859
  // mutation retries.
7665
7860
  __publicField(this, "historyFailed", /* @__PURE__ */ new Set());
7861
+ // Compiled-handle cache (issue #106 perf): buildHandle compiles 8 + (one per
7862
+ // mutation) East.functions per bind, and binds re-run every reactive frame.
7863
+ // The method IR is a pure function of the record name (which fixes the handle
7864
+ // type), and the methods resolve cache/api/ws LIVE, so a cached handle still
7865
+ // re-binds. Cleared on clear().
7866
+ __publicField(this, "handleCache", /* @__PURE__ */ new Map());
7666
7867
  }
7667
7868
  createEntry() {
7668
7869
  return { status: "idle", launchSeq: 0 };
@@ -7685,6 +7886,7 @@ class RecordRuntime extends TrackedChannelStore {
7685
7886
  this.histories.clear();
7686
7887
  this.historyInFlight.clear();
7687
7888
  this.historyFailed.clear();
7889
+ this.handleCache.clear();
7688
7890
  }
7689
7891
  resolveWorkspace() {
7690
7892
  if (!this.workspace) {
@@ -7803,96 +8005,170 @@ class RecordRuntime extends TrackedChannelStore {
7803
8005
  if (current && current.inflight === run) delete current.inflight;
7804
8006
  });
7805
8007
  }
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);
8008
+ /**
8009
+ * The low-level primitives backing handle methods, bound to THIS runtime.
8010
+ * Registered globally (extension registry) and included by the scoped
8011
+ * platform (e3 `ui()` tasks) so a decoded handle re-binds here. The host
8012
+ * effects (dataset-cache reads + reactive tracking + mutation launch) live
8013
+ * here, keyed only on the plain-data record name; the state type rides as a
8014
+ * type-arg on `record_read`, and per-mutation arg types come from the
8015
+ * `record_mutate` ArgsStruct type-arg.
8016
+ */
8017
+ buildPrimitives() {
7810
8018
  const runtime = this;
7811
- const path2 = recordPath(name);
7812
8019
  const requireCache = () => {
7813
8020
  if (!runtime.cache) {
7814
8021
  throw new Error("Record.bind: no dataset cache configured — mount a provider first");
7815
8022
  }
7816
8023
  return runtime.cache;
7817
8024
  };
7818
- const mutate = {
7819
- pending: () => {
8025
+ return [
8026
+ internal$1.RecordBindPrimitives.read.implement((stateType) => {
8027
+ const decode = east.decodeBeast2For(stateType);
8028
+ return (nameArg) => {
8029
+ const ws = runtime.resolveWorkspace();
8030
+ const path2 = recordPath(nameArg);
8031
+ trackDatasetPath(ws, path2);
8032
+ const bytes = requireCache().read(ws, path2);
8033
+ if (bytes === void 0) {
8034
+ throw new Error(`Record.bind: record state not loaded: ${datasetCacheKey(ws, path2)} (it should be preloaded via the UI task manifest)`);
8035
+ }
8036
+ return decode(bytes);
8037
+ };
8038
+ }),
8039
+ internal$1.RecordBindPrimitives.status.implement((nameArg) => {
8040
+ const ws = runtime.resolveWorkspace();
8041
+ const path2 = recordPath(nameArg);
8042
+ trackDatasetPath(ws, path2);
8043
+ return requireCache().getStatus(ws, path2);
8044
+ }),
8045
+ internal$1.RecordBindPrimitives.history.implement((nameArg) => {
8046
+ const name = nameArg;
7820
8047
  const ws = runtime.resolveWorkspace();
7821
8048
  const key = recordChannelKey(ws, name);
7822
8049
  runtime.track(key);
8050
+ const cached = runtime.histories.get(key);
8051
+ if (cached === void 0) {
8052
+ if (!runtime.historyFailed.has(key)) runtime.fetchHistory(ws, name, key);
8053
+ return east.none;
8054
+ }
8055
+ return east.some(cached);
8056
+ }),
8057
+ internal$1.RecordBindPrimitives.start.implement((nameArg) => {
8058
+ const ws = runtime.resolveWorkspace();
8059
+ const cache3 = requireCache();
8060
+ const inflight = runtime.entry(recordChannelKey(ws, nameArg)).inflight;
8061
+ void Promise.resolve(inflight).catch(() => void 0).then(() => cache3.launchDataflow(ws)).catch(() => void 0);
8062
+ return null;
8063
+ }),
8064
+ internal$1.RecordBindPrimitives.mutatePending.implement((nameArg) => {
8065
+ const ws = runtime.resolveWorkspace();
8066
+ const key = recordChannelKey(ws, nameArg);
8067
+ runtime.track(key);
7823
8068
  return runtime.entry(key).status === "running";
7824
- },
7825
- status: () => {
8069
+ }),
8070
+ internal$1.RecordBindPrimitives.mutateStatus.implement((nameArg) => {
7826
8071
  const ws = runtime.resolveWorkspace();
7827
- const key = recordChannelKey(ws, name);
8072
+ const key = recordChannelKey(ws, nameArg);
7828
8073
  runtime.track(key);
7829
8074
  return east.variant(runtime.entry(key).status, null);
7830
- },
7831
- error: () => {
8075
+ }),
8076
+ internal$1.RecordBindPrimitives.mutateError.implement((nameArg) => {
7832
8077
  const ws = runtime.resolveWorkspace();
7833
- const key = recordChannelKey(ws, name);
8078
+ const key = recordChannelKey(ws, nameArg);
7834
8079
  runtime.track(key);
7835
8080
  const entry = runtime.entry(key);
7836
8081
  return entry.status === "failed" && entry.error !== void 0 ? east.some(entry.error) : east.none;
7837
- },
7838
- cancel: () => {
8082
+ }),
8083
+ internal$1.RecordBindPrimitives.mutateCancel.implement((nameArg) => {
7839
8084
  const ws = runtime.resolveWorkspace();
7840
- runtime.cancelChannel(recordChannelKey(ws, name), (e3) => {
8085
+ runtime.cancelChannel(recordChannelKey(ws, nameArg), (e3) => {
7841
8086
  delete e3.error;
7842
8087
  delete e3.inflight;
7843
8088
  });
7844
8089
  return null;
7845
- }
8090
+ }),
8091
+ internal$1.RecordBindPrimitives.mutate.implement((argsStructType) => (recordNameArg, mutationNameArg, argsStruct) => {
8092
+ const fields = argsStructType.value;
8093
+ const obj = argsStruct;
8094
+ const argTypes = fields.map((f2) => f2.type);
8095
+ const args = fields.map((f2) => obj[f2.name]);
8096
+ runtime.launchMutation(runtime.resolveWorkspace(), recordNameArg, mutationNameArg, argTypes, args);
8097
+ return null;
8098
+ })
8099
+ ];
8100
+ }
8101
+ /**
8102
+ * Build the handle value for one `Record.bind` evaluation. Every method —
8103
+ * top-level AND nested `mutate.*` (incl. the dynamic per-mutation closures) —
8104
+ * is a thin IR-bearing `East.function` over {@link buildPrimitives}, capturing
8105
+ * only the record name (+ per-mutation name), so the handle is ordinary
8106
+ * serializable East data (issue #106).
8107
+ */
8108
+ buildHandle(handleType, name) {
8109
+ const cached = this.handleCache.get(name);
8110
+ if (cached) return cached;
8111
+ const sig = signatureOfRecordHandleType(handleType);
8112
+ const stateTypeEast = east.fromEastTypeValue(sig.stateType);
8113
+ const fields = handleType.value;
8114
+ const fnOut = (list, n2) => east.fromEastTypeValue(list.find((f2) => f2.name === n2).type.value.output);
8115
+ const statusRet = fnOut(fields, "status");
8116
+ const historyRet = fnOut(fields, "history");
8117
+ const mfields = fields.find((f2) => f2.name === "mutate").type.value;
8118
+ const nameExpr = east.East.value(name, east.StringType);
8119
+ const platform2 = this.buildPrimitives();
8120
+ const P2 = internal$1.RecordBindPrimitives;
8121
+ const mutate = {
8122
+ pending: east.East.compile(east.East.function([], fnOut(mfields, "pending"), ($3) => {
8123
+ $3.return(P2.mutatePending(nameExpr));
8124
+ }), platform2),
8125
+ status: east.East.compile(east.East.function([], fnOut(mfields, "status"), ($3) => {
8126
+ $3.return(P2.mutateStatus(nameExpr));
8127
+ }), platform2),
8128
+ error: east.East.compile(east.East.function([], fnOut(mfields, "error"), ($3) => {
8129
+ $3.return(P2.mutateError(nameExpr));
8130
+ }), platform2),
8131
+ cancel: east.East.compile(east.East.function([], east.NullType, ($3) => {
8132
+ $3.return(P2.mutateCancel(nameExpr));
8133
+ }), platform2)
7846
8134
  };
7847
8135
  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
- },
8136
+ const argTypesEast = argTypes.map((t4) => east.fromEastTypeValue(t4));
8137
+ const ArgsStruct = east.StructType(Object.fromEntries(argTypesEast.map((t4, i) => [`arg${i}`, t4])));
8138
+ const mutationNameExpr = east.East.value(mutationName, east.StringType);
8139
+ mutate[mutationName] = east.East.compile(east.East.function(argTypesEast, east.NullType, ($3, ...args) => {
8140
+ const obj = {};
8141
+ args.forEach((a2, i) => {
8142
+ obj[`arg${i}`] = a2;
8143
+ });
8144
+ $3.return(P2.mutate([ArgsStruct], nameExpr, mutationNameExpr, east.East.value(obj, ArgsStruct)));
8145
+ }), platform2);
8146
+ }
8147
+ const handle = {
8148
+ read: east.East.compile(east.East.function([], stateTypeEast, ($3) => {
8149
+ $3.return(P2.read([stateTypeEast], nameExpr));
8150
+ }), platform2),
8151
+ status: east.East.compile(east.East.function([], statusRet, ($3) => {
8152
+ $3.return(P2.status(nameExpr));
8153
+ }), platform2),
8154
+ history: east.East.compile(east.East.function([], historyRet, ($3) => {
8155
+ $3.return(P2.history(nameExpr));
8156
+ }), platform2),
7879
8157
  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
- },
8158
+ start: east.East.compile(east.East.function([], east.NullType, ($3) => {
8159
+ $3.return(P2.start(nameExpr));
8160
+ }), platform2),
7887
8161
  binding: { name, mutations: [...sig.mutations.keys()] }
7888
8162
  };
8163
+ this.handleCache.set(name, handle);
8164
+ return handle;
7889
8165
  }
7890
8166
  // ----- platform building -------------------------------------------------
7891
8167
  /** Build a `Record.bind` PlatformFunction bound to this runtime. Pass
7892
8168
  * `allowed=null` for an unscoped impl; pass a Set of record names for
7893
8169
  * manifest scoping. */
7894
8170
  buildPlatform(allowed) {
7895
- return internal.recordBindPlatformFn.implement(
8171
+ return internal$1.recordBindPlatformFn.implement(
7896
8172
  (handleType) => (nameArg) => {
7897
8173
  const name = nameArg;
7898
8174
  if (allowed && !allowed.has(name)) {
@@ -7912,9 +8188,15 @@ function initializeRecordApi(api3, cache3, workspace) {
7912
8188
  function clearRecordApi() {
7913
8189
  defaultRecordRuntime.clear();
7914
8190
  }
7915
- const RecordPlatform = [defaultRecordRuntime.buildPlatform(null)];
8191
+ const RecordPlatform = [
8192
+ defaultRecordRuntime.buildPlatform(null),
8193
+ ...defaultRecordRuntime.buildPrimitives()
8194
+ ];
7916
8195
  function createScopedRecordPlatform(records) {
7917
- return [defaultRecordRuntime.buildPlatform(new Set(records))];
8196
+ return [
8197
+ defaultRecordRuntime.buildPlatform(new Set(records)),
8198
+ ...defaultRecordRuntime.buildPrimitives()
8199
+ ];
7918
8200
  }
7919
8201
  function createInMemoryRecordApi(cache3, workspace, defs2) {
7920
8202
  const compiled = /* @__PURE__ */ new Map();
@@ -8343,7 +8625,7 @@ function parseManualDraft(leafType, draft) {
8343
8625
  return { ok: false };
8344
8626
  }
8345
8627
  }
8346
- const diffValueEqual = east.equalFor(internal.Diff.Component.schema);
8628
+ const diffValueEqual = east.equalFor(internal$1.Diff.Component.schema);
8347
8629
  function getOpt$1(opt) {
8348
8630
  return opt.type === "some" ? opt.value : void 0;
8349
8631
  }
@@ -9331,7 +9613,7 @@ const EastChakraDiff = React.memo(function EastChakraDiff2({ value }) {
9331
9613
  function rowKey(pathStr, leafPath) {
9332
9614
  return `${pathStr}::${leafPath}`;
9333
9615
  }
9334
- eastUiComponents.implementUIComponent(internal.Diff.Component, EastChakraDiff);
9616
+ eastUiComponents.implementUIComponent(internal$1.Diff.Component, EastChakraDiff);
9335
9617
  function cc(names) {
9336
9618
  if (typeof names === "string" || typeof names === "number") return "" + names;
9337
9619
  let out = "";
@@ -57242,7 +57524,7 @@ const EastChakraOntology = React.memo(function EastChakraOntology2({ value }) {
57242
57524
  }
57243
57525
  );
57244
57526
  });
57245
- eastUiComponents.implementUIComponent(internal.Ontology.Component, EastChakraOntology);
57527
+ eastUiComponents.implementUIComponent(internal$1.Ontology.Component, EastChakraOntology);
57246
57528
  const EMPTY_PATH = [];
57247
57529
  function useBindingVersion(workspace, sourcePath, patchPath) {
57248
57530
  const staged = getStagedStore();
@@ -57309,7 +57591,7 @@ function useFuncCall(name, inputs, output2) {
57309
57591
  );
57310
57592
  const handle = React.useMemo(() => {
57311
57593
  if (!ready4) return null;
57312
- const handleType = east.toEastTypeValue(internal.FuncBindHandleType(inputs, output2));
57594
+ const handleType = east.toEastTypeValue(internal$1.FuncBindHandleType(inputs, output2));
57313
57595
  return defaultFuncRuntime.buildHandle(handleType, name);
57314
57596
  }, [ready4, name, workspace, sigKey]);
57315
57597
  const channelKey = ready4 ? funcChannelKey(workspace, name) : "";
@@ -60755,7 +61037,7 @@ function LoadingSkeleton() {
60755
61037
  ] })
60756
61038
  ] });
60757
61039
  }
60758
- const experimentValueEqual = east.equalFor(internal.Experiment.Component.schema);
61040
+ const experimentValueEqual = east.equalFor(internal$1.Experiment.Component.schema);
60759
61041
  const EastChakraExperiment = React.memo(function EastChakraExperiment2({ value }) {
60760
61042
  var _a2, _b2, _c2;
60761
61043
  const v3 = value;
@@ -60824,16 +61106,16 @@ const EastChakraExperiment = React.memo(function EastChakraExperiment2({ value }
60824
61106
  }),
60825
61107
  [columns, meta3]
60826
61108
  );
60827
- const estInputs = React.useMemo(() => rowArrayType ? [rowArrayType, internal.Experiment.Types.Config] : null, [rowArrayType]);
60828
- const experiment = useFuncCall(v3.experiment.type === "some" ? v3.experiment.value.name : null, estInputs, internal.Experiment.Types.Result);
61109
+ const estInputs = React.useMemo(() => rowArrayType ? [rowArrayType, internal$1.Experiment.Types.Config] : null, [rowArrayType]);
61110
+ const experiment = useFuncCall(v3.experiment.type === "some" ? v3.experiment.value.name : null, estInputs, internal$1.Experiment.Types.Result);
60829
61111
  const hasExperiment = v3.experiment.type === "some";
60830
61112
  const shownResult = experiment.result ?? eastUiComponents.getSomeorUndefined(selectedEntry == null ? void 0 : selectedEntry.result) ?? null;
60831
61113
  const hasDesign = v3.design.type === "some";
60832
61114
  const designInputs = React.useMemo(
60833
- () => rowArrayType ? [rowArrayType, internal.Experiment.Types.Config, internal.Experiment.Types.Result, internal.Experiment.Types.DesignConfig] : null,
61115
+ () => rowArrayType ? [rowArrayType, internal$1.Experiment.Types.Config, internal$1.Experiment.Types.Result, internal$1.Experiment.Types.DesignConfig] : null,
60834
61116
  [rowArrayType]
60835
61117
  );
60836
- const design = useFuncCall(v3.design.type === "some" ? v3.design.value.name : null, designInputs, internal.Experiment.Types.Design);
61118
+ const design = useFuncCall(v3.design.type === "some" ? v3.design.value.name : null, designInputs, internal$1.Experiment.Types.Design);
60837
61119
  const pendingConfigRef = React.useRef(null);
60838
61120
  const [ranConfig, setRanConfig] = React.useState(null);
60839
61121
  const runAll = React.useCallback(() => {
@@ -61574,7 +61856,7 @@ function Segmented({ label, left, right, active, onPick, last: last2, help, read
61574
61856
  readonly ? /* @__PURE__ */ jsxRuntime.jsx(SegmentStatic, { value: active === "left" ? left : right }) : /* @__PURE__ */ jsxRuntime.jsx(SegmentSelect, { options: [left, right], active: active === "left" ? 0 : 1, onPick: (i) => onPick(i === 0 ? "left" : "right"), fill: true, size: "xs" })
61575
61857
  ] });
61576
61858
  }
61577
- eastUiComponents.implementUIComponent(internal.Experiment.Component, EastChakraExperiment);
61859
+ eastUiComponents.implementUIComponent(internal$1.Experiment.Component, EastChakraExperiment);
61578
61860
  const SELECTION_TYPE = east.OptionType(east.StringType);
61579
61861
  const encodeSelection = east.encodeBeast2For(SELECTION_TYPE);
61580
61862
  const decodeSelection = east.decodeBeast2For(SELECTION_TYPE);
@@ -61622,23 +61904,23 @@ function hashString2(s2) {
61622
61904
  for (let i = 0; i < s2.length; i++) h2 = (h2 << 5) + h2 + s2.charCodeAt(i) | 0;
61623
61905
  return (h2 >>> 0).toString(36);
61624
61906
  }
61625
- function buildDecisionHandle(decisions, judgements, sliceInit) {
61626
- const selectionKey = deriveSelectionKey(decisions);
61627
- const readSelection = () => {
61628
- eastUiComponents.StateRuntime.trackKey(selectionKey);
61629
- const bytes = eastUiComponents.StateRuntime.getStore().read(selectionKey);
61630
- return bytes === void 0 ? east.none : decodeSelection(bytes);
61631
- };
61632
- const writeSelection = (value) => {
61633
- eastUiComponents.StateRuntime.getStore().write(selectionKey, encodeSelection(value));
61634
- return null;
61635
- };
61636
- const queue = () => decisions.flatMap((b2) => viewFor(b2).read());
61637
- const readJudgements = () => viewFor(judgements).read();
61638
- const writeJudgements = (next2) => {
61639
- viewFor(judgements).write(next2);
61640
- };
61641
- const judgementFor = (caseId) => readJudgements().get(caseId) ?? {
61907
+ function readSelectionAt(selectionKey) {
61908
+ platform.StateRuntime.trackKey(selectionKey);
61909
+ const bytes = platform.StateRuntime.getStore().read(selectionKey);
61910
+ return bytes === void 0 ? east.none : decodeSelection(bytes);
61911
+ }
61912
+ function writeSelectionAt(selectionKey, value) {
61913
+ platform.StateRuntime.getStore().write(selectionKey, encodeSelection(value));
61914
+ return null;
61915
+ }
61916
+ function hostQueue(decisions) {
61917
+ return decisions.flatMap((b2) => viewFor(b2).read());
61918
+ }
61919
+ function readJudgementsAt(judgements) {
61920
+ return viewFor(judgements).read();
61921
+ }
61922
+ function judgementForAt(judgements, caseId) {
61923
+ return readJudgementsAt(judgements).get(caseId) ?? {
61642
61924
  caseId,
61643
61925
  answers: /* @__PURE__ */ new Map(),
61644
61926
  knowledge: east.none,
@@ -61646,105 +61928,194 @@ function buildDecisionHandle(decisions, judgements, sliceInit) {
61646
61928
  verdict: east.none,
61647
61929
  resolvedAt: east.none
61648
61930
  };
61649
- const stageJudgement = (caseId, change) => {
61650
- const dict = new Map(readJudgements());
61651
- dict.set(caseId, { ...judgementFor(caseId), ...change });
61652
- writeJudgements(dict);
61653
- return null;
61654
- };
61655
- const removeFromOwningView = (caseId) => {
61656
- for (const binding of decisions) {
61657
- const view = viewFor(binding);
61658
- const rows = view.read();
61659
- if (rows.some((d2) => d2.id === caseId)) {
61660
- view.write(rows.filter((d2) => d2.id !== caseId));
61661
- }
61931
+ }
61932
+ function stageJudgementAt(judgements, caseId, change) {
61933
+ const dict = new Map(readJudgementsAt(judgements));
61934
+ dict.set(caseId, { ...judgementForAt(judgements, caseId), ...change });
61935
+ viewFor(judgements).write(dict);
61936
+ return null;
61937
+ }
61938
+ function removeFromOwningView(decisions, caseId) {
61939
+ for (const binding of decisions) {
61940
+ const view = viewFor(binding);
61941
+ const rows = view.read();
61942
+ if (rows.some((d2) => d2.id === caseId)) {
61943
+ view.write(rows.filter((d2) => d2.id !== caseId));
61662
61944
  }
61663
- };
61664
- const slice3 = eastUiComponents.buildSliceHandle(
61945
+ }
61946
+ }
61947
+ const decisionHandleCache = /* @__PURE__ */ new Map();
61948
+ function typeToken(tv) {
61949
+ const seen = /* @__PURE__ */ new WeakSet();
61950
+ return JSON.stringify(tv, (_k, v3) => {
61951
+ if (typeof v3 === "object" && v3 !== null) {
61952
+ if (seen.has(v3)) return "<cyc>";
61953
+ seen.add(v3);
61954
+ }
61955
+ return typeof v3 === "bigint" ? `${v3}n` : v3;
61956
+ });
61957
+ }
61958
+ function compileDecisionMethods(constraintType, decisions, judgements, selectionKey) {
61959
+ const platform$1 = platform.getRegisteredPlatformImplementations();
61960
+ const c2 = east.fromEastTypeValue(constraintType);
61961
+ const decisionsExpr = east.East.value(decisions, east.ArrayType(internal$1.DiffBindingType));
61962
+ const judgementsExpr = east.East.value(judgements, internal$1.DiffBindingType);
61963
+ const selKeyExpr = east.East.value(selectionKey, east.StringType);
61964
+ const {
61965
+ queue,
61966
+ selected: selected2,
61967
+ select: select2,
61968
+ clearSelection,
61969
+ decision,
61970
+ update: update2,
61971
+ judgement,
61972
+ answer,
61973
+ addKnowledge,
61974
+ inject,
61975
+ resolve: resolve2,
61976
+ commitState
61977
+ } = internal$1.DecisionBindPrimitives;
61978
+ return {
61979
+ queue: east.East.compile(east.East.function([], east.ArrayType(internal$1.DecisionType), ($3) => {
61980
+ $3.return(queue(decisionsExpr));
61981
+ }), platform$1),
61982
+ selected: east.East.compile(east.East.function([], east.OptionType(east.StringType), ($3) => {
61983
+ $3.return(selected2(selKeyExpr));
61984
+ }), platform$1),
61985
+ select: east.East.compile(east.East.function([east.StringType], east.NullType, ($3, id3) => {
61986
+ $3.return(select2(selKeyExpr, id3));
61987
+ }), platform$1),
61988
+ clearSelection: east.East.compile(east.East.function([], east.NullType, ($3) => {
61989
+ $3.return(clearSelection(selKeyExpr));
61990
+ }), platform$1),
61991
+ decision: east.East.compile(east.East.function([], east.OptionType(internal$1.DecisionType), ($3) => {
61992
+ $3.return(decision(decisionsExpr, selKeyExpr));
61993
+ }), platform$1),
61994
+ update: east.East.compile(east.East.function([internal$1.DecisionType], east.NullType, ($3, edited) => {
61995
+ $3.return(update2(decisionsExpr, edited));
61996
+ }), platform$1),
61997
+ judgement: east.East.compile(east.East.function([east.StringType], internal$1.judgementInputType(c2), ($3, id3) => {
61998
+ $3.return(judgement([c2], judgementsExpr, id3));
61999
+ }), platform$1),
62000
+ answer: east.East.compile(east.East.function([east.StringType, east.StringType, internal$1.AnswerType], east.NullType, ($3, id3, prompt, ans) => {
62001
+ $3.return(answer(judgementsExpr, id3, prompt, ans));
62002
+ }), platform$1),
62003
+ addKnowledge: east.East.compile(east.East.function([east.StringType, east.StringType], east.NullType, ($3, id3, text) => {
62004
+ $3.return(addKnowledge(judgementsExpr, id3, text));
62005
+ }), platform$1),
62006
+ inject: east.East.compile(east.East.function([east.StringType, c2], east.NullType, ($3, id3, con) => {
62007
+ $3.return(inject([c2], judgementsExpr, id3, con));
62008
+ }), platform$1),
62009
+ resolve: east.East.compile(east.East.function([east.StringType, internal$1.VerdictType], east.NullType, ($3, id3, verdict) => {
62010
+ $3.return(resolve2(decisionsExpr, judgementsExpr, selKeyExpr, id3, verdict));
62011
+ }), platform$1),
62012
+ commitState: east.East.compile(east.East.function([east.StringType], internal$1.CommitStateType, ($3, id3) => {
62013
+ $3.return(commitState(decisionsExpr, judgementsExpr, id3));
62014
+ }), platform$1)
62015
+ };
62016
+ }
62017
+ function buildDecisionHandle(decisions, judgements, sliceInit, constraintType) {
62018
+ const cType = constraintType ?? east.toEastTypeValue(internal$1.DecisionConstraintType);
62019
+ const selectionKey = deriveSelectionKey(decisions);
62020
+ const slice3 = platform.buildSliceHandle(
61665
62021
  deriveSliceKey(decisions, sliceInit),
61666
62022
  DECISION_SLICE_CONFIG,
61667
- sliceInit ?? eastUiComponents.DEFAULT_SLICE_STATE,
61668
- () => queue(),
62023
+ sliceInit ?? platform.DEFAULT_SLICE_STATE,
62024
+ () => hostQueue(decisions),
61669
62025
  east.none
61670
62026
  );
62027
+ const journal = () => {
62028
+ const entries = [...readJudgementsAt(judgements).values()].filter((j2) => j2.verdict.type === "some");
62029
+ const at = (j2) => j2.resolvedAt.type === "some" ? j2.resolvedAt.value.getTime() : 0;
62030
+ return entries.sort((a2, b2) => at(b2) - at(a2));
62031
+ };
62032
+ const cacheKey = `${hashString2(stableStringify({ decisions, judgements }))}|${typeToken(cType)}`;
62033
+ let methods = decisionHandleCache.get(cacheKey);
62034
+ if (methods === void 0) {
62035
+ methods = compileDecisionMethods(cType, decisions, judgements, selectionKey);
62036
+ decisionHandleCache.set(cacheKey, methods);
62037
+ }
61671
62038
  return {
61672
62039
  decisions,
61673
62040
  judgements,
61674
62041
  sliceInit: sliceInit !== void 0 ? east.some(sliceInit) : east.none,
61675
62042
  slice: slice3,
61676
- queue,
61677
- selected: readSelection,
61678
- select: (caseId) => writeSelection(east.some(caseId)),
61679
- clearSelection: () => writeSelection(east.none),
61680
- decision: () => {
61681
- const selection2 = readSelection();
61682
- if (selection2.type === "none") return east.none;
61683
- const found = queue().find((d2) => d2.id === selection2.value);
61684
- return found === void 0 ? east.none : east.some(found);
61685
- },
61686
- update: (edited) => {
61687
- for (const binding of decisions) {
61688
- const view = viewFor(binding);
61689
- const rows = view.read();
61690
- if (rows.some((d2) => d2.id === edited.id)) {
61691
- view.write(rows.map((d2) => d2.id === edited.id ? edited : d2));
61692
- }
61693
- }
61694
- return null;
61695
- },
61696
- judgement: judgementFor,
61697
- answer: (caseId, prompt, response) => {
61698
- const answers = new Map(judgementFor(caseId).answers);
61699
- answers.set(prompt, response);
61700
- return stageJudgement(caseId, { answers });
61701
- },
61702
- addKnowledge: (caseId, text) => stageJudgement(caseId, { knowledge: east.some(text) }),
61703
- inject: (caseId, constraint) => {
61704
- const constraints = judgementFor(caseId).constraints.filter((c2) => c2.type !== constraint.type).concat([constraint]);
61705
- return stageJudgement(caseId, { constraints });
61706
- },
61707
- resolve: (caseId, verdict) => {
61708
- stageJudgement(caseId, { verdict: east.some(verdict), resolvedAt: east.some(/* @__PURE__ */ new Date()) });
61709
- removeFromOwningView(caseId);
61710
- writeSelection(east.none);
61711
- return null;
61712
- },
61713
- journal: () => {
61714
- const entries = [...readJudgements().values()].filter((j2) => j2.verdict.type === "some");
61715
- const at = (j2) => j2.resolvedAt.type === "some" ? j2.resolvedAt.value.getTime() : 0;
61716
- return entries.sort((a2, b2) => at(b2) - at(a2));
61717
- },
61718
- commitState: (caseId) => {
61719
- const decision = queue().find((d2) => d2.id === caseId);
61720
- const prompts = (decision == null ? void 0 : decision.prompts) ?? [];
61721
- const answers = judgementFor(caseId).answers;
61722
- const responses = prompts.map((p2) => {
61723
- var _a2;
61724
- return (_a2 = answers.get(p2.id)) == null ? void 0 : _a2.type;
61725
- });
61726
- if (responses.some((r2) => r2 === "no")) return east.variant("blocked", null);
61727
- if (responses.some((r2) => r2 === "unknown")) return east.variant("handoff", null);
61728
- const unanswered = responses.filter((r2) => r2 === void 0).length;
61729
- if (unanswered > 0) return east.variant("gated", BigInt(unanswered));
61730
- return east.variant("ready", null);
61731
- }
62043
+ journal,
62044
+ ...methods
61732
62045
  };
61733
62046
  }
61734
62047
  const DecisionBindPlatform = [
61735
- // Generic over the constraint contract — the type argument resolver
61736
- // receives the contract type value; the JS impl is type-agnostic.
61737
- internal.decisionBindPlatformFn.implement((_constraintType) => (decisionsArg, judgementsArg, sliceInitArg) => buildDecisionHandle(
62048
+ // Generic over the constraint contract — the resolver receives the contract
62049
+ // type value and threads it into the IR-bearing judgement / inject methods.
62050
+ internal$1.decisionBindPlatformFn.implement((constraintType) => (decisionsArg, judgementsArg, sliceInitArg) => buildDecisionHandle(
61738
62051
  decisionsArg,
61739
62052
  judgementsArg,
61740
- eastUiComponents.getSomeorUndefined(sliceInitArg)
61741
- ))
62053
+ platform.getSomeorUndefined(sliceInitArg),
62054
+ constraintType
62055
+ )),
62056
+ // ── issue #106 primitives — host I/O backing the IR-bearing handle methods.
62057
+ // Each is a faithful lift of the original closure body, taking the plain-data
62058
+ // descriptor(s) + the selection key as arguments. ──
62059
+ internal$1.DecisionBindPrimitives.queue.implement((decisions) => hostQueue(decisions)),
62060
+ internal$1.DecisionBindPrimitives.selected.implement((selectionKey) => readSelectionAt(selectionKey)),
62061
+ internal$1.DecisionBindPrimitives.select.implement((selectionKey, caseId) => writeSelectionAt(selectionKey, east.some(caseId))),
62062
+ internal$1.DecisionBindPrimitives.clearSelection.implement((selectionKey) => writeSelectionAt(selectionKey, east.none)),
62063
+ internal$1.DecisionBindPrimitives.decision.implement((decisions, selectionKey) => {
62064
+ const sel = readSelectionAt(selectionKey);
62065
+ if (sel.type === "none") return east.none;
62066
+ const found = hostQueue(decisions).find((d2) => d2.id === sel.value);
62067
+ return found === void 0 ? east.none : east.some(found);
62068
+ }),
62069
+ internal$1.DecisionBindPrimitives.update.implement((decisions, edited) => {
62070
+ const e3 = edited;
62071
+ for (const binding of decisions) {
62072
+ const view = viewFor(binding);
62073
+ const rows = view.read();
62074
+ if (rows.some((d2) => d2.id === e3.id)) {
62075
+ view.write(rows.map((d2) => d2.id === e3.id ? e3 : d2));
62076
+ }
62077
+ }
62078
+ return null;
62079
+ }),
62080
+ internal$1.DecisionBindPrimitives.judgement.implement((_c2) => (judgements, caseId) => judgementForAt(judgements, caseId)),
62081
+ internal$1.DecisionBindPrimitives.answer.implement((judgements, caseId, prompt, response) => {
62082
+ const answers = new Map(judgementForAt(judgements, caseId).answers);
62083
+ answers.set(prompt, response);
62084
+ return stageJudgementAt(judgements, caseId, { answers });
62085
+ }),
62086
+ internal$1.DecisionBindPrimitives.addKnowledge.implement((judgements, caseId, text) => stageJudgementAt(judgements, caseId, { knowledge: east.some(text) })),
62087
+ internal$1.DecisionBindPrimitives.inject.implement((_c2) => (judgements, caseId, constraint) => {
62088
+ const con = constraint;
62089
+ const constraints = judgementForAt(judgements, caseId).constraints.filter((x2) => x2.type !== con.type).concat([con]);
62090
+ return stageJudgementAt(judgements, caseId, { constraints });
62091
+ }),
62092
+ internal$1.DecisionBindPrimitives.resolve.implement((decisions, judgements, selectionKey, caseId, verdict) => {
62093
+ stageJudgementAt(judgements, caseId, { verdict: east.some(verdict), resolvedAt: east.some(/* @__PURE__ */ new Date()) });
62094
+ removeFromOwningView(decisions, caseId);
62095
+ writeSelectionAt(selectionKey, east.none);
62096
+ return null;
62097
+ }),
62098
+ internal$1.DecisionBindPrimitives.commitState.implement((decisions, judgements, caseId) => {
62099
+ const cid = caseId;
62100
+ const decision = hostQueue(decisions).find((d2) => d2.id === cid);
62101
+ const prompts = (decision == null ? void 0 : decision.prompts) ?? [];
62102
+ const answers = judgementForAt(judgements, cid).answers;
62103
+ const responses = prompts.map((p2) => {
62104
+ var _a2;
62105
+ return (_a2 = answers.get(p2.id)) == null ? void 0 : _a2.type;
62106
+ });
62107
+ if (responses.some((r2) => r2 === "no")) return east.variant("blocked", null);
62108
+ if (responses.some((r2) => r2 === "unknown")) return east.variant("handoff", null);
62109
+ const unanswered = responses.filter((r2) => r2 === void 0).length;
62110
+ if (unanswered > 0) return east.variant("gated", BigInt(unanswered));
62111
+ return east.variant("ready", null);
62112
+ })
61742
62113
  ];
61743
- eastUiComponents.registerPlatformImplementation(DecisionBindPlatform);
62114
+ platform.registerPlatformImplementation(DecisionBindPlatform);
61744
62115
  function useHandleVersion(handle) {
61745
62116
  const staged = getStagedStore();
61746
62117
  const cache3 = getReactiveDatasetCache();
61747
- const state = eastUiComponents.StateRuntime.getStore();
62118
+ const state = platform.StateRuntime.getStore();
61748
62119
  const workspace = cache3.getConfig().workspace ?? "";
61749
62120
  const keys = React.useMemo(() => {
61750
62121
  if (!handle) return [];
@@ -61776,7 +62147,7 @@ function useDecisionHandle(ref) {
61776
62147
  () => ref ? buildDecisionHandle(
61777
62148
  [...ref.decisions],
61778
62149
  ref.judgements,
61779
- eastUiComponents.getSomeorUndefined(ref.slice)
62150
+ platform.getSomeorUndefined(ref.slice)
61780
62151
  ) : null,
61781
62152
  [ref]
61782
62153
  );
@@ -62126,6 +62497,9 @@ const OptionsFacet = React.memo(function OptionsFacet2({ decision, narrow }) {
62126
62497
  const options2 = rankOptions(decision);
62127
62498
  const maxUp = Math.max(...options2.map((o2) => Math.max(o2.value, 0)), 1e-9);
62128
62499
  const maxDown = Math.max(...options2.map((o2) => Math.abs(o2.downside ?? 0)), 1e-9);
62500
+ const valueAxis = eastUiComponents.getSomeorUndefined(decision.valueAxis);
62501
+ const upLabel = (valueAxis == null ? void 0 : valueAxis.label) ?? "Uplift";
62502
+ const signed2 = (valueAxis == null ? void 0 : valueAxis.signed) ?? true;
62129
62503
  if (narrow) {
62130
62504
  const meter = (label, frac, display, tone) => /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { display: "grid", gridTemplateColumns: "80px 1fr 64px", alignItems: "center", gap: "8px", children: [
62131
62505
  /* @__PURE__ */ jsxRuntime.jsx(react.Text, { ...caption, whiteSpace: "nowrap", children: label }),
@@ -62144,7 +62518,7 @@ const OptionsFacet = React.memo(function OptionsFacet2({ decision, narrow }) {
62144
62518
  " ",
62145
62519
  /* @__PURE__ */ jsxRuntime.jsx(react.Text, { as: "span", fontWeight: o2.recommended ? "semibold" : "normal", children: o2.label })
62146
62520
  ] }),
62147
- meter("Uplift", o2.value / maxUp, fmt(decision, o2.value, true), "success"),
62521
+ meter(upLabel, o2.value / maxUp, fmt(decision, o2.value, signed2), signed2 ? "success" : "neutral"),
62148
62522
  meter("If wrong", (o2.downside ?? 0) / maxDown, o2.downside !== void 0 ? fmt(decision, o2.downside, true) : "—", "danger")
62149
62523
  ] }, o2.rank))
62150
62524
  ] });
@@ -62157,7 +62531,7 @@ const OptionsFacet = React.memo(function OptionsFacet2({ decision, narrow }) {
62157
62531
  " evaluated"
62158
62532
  ] }),
62159
62533
  /* @__PURE__ */ jsxRuntime.jsx(react.Text, { ...caption, textAlign: "center", children: "If wrong" }),
62160
- /* @__PURE__ */ jsxRuntime.jsx(react.Text, { ...caption, textAlign: "right", children: "Uplift" })
62534
+ /* @__PURE__ */ jsxRuntime.jsx(react.Text, { ...caption, textAlign: "right", children: upLabel })
62161
62535
  ] }),
62162
62536
  options2.map((o2) => {
62163
62537
  const downFrac = Math.min(Math.abs(o2.downside ?? 0) / maxDown, 1);
@@ -62182,8 +62556,8 @@ const OptionsFacet = React.memo(function OptionsFacet2({ decision, narrow }) {
62182
62556
  /* @__PURE__ */ jsxRuntime.jsx(react.Box, { height: "12px", width: `${Math.round(downFrac * 100)}%`, bg: "fg.danger", opacity: 0.55 })
62183
62557
  ] }) }),
62184
62558
  /* @__PURE__ */ jsxRuntime.jsx(react.Box, { display: "flex", alignItems: "center", gap: "6px", height: "16px", borderLeftWidth: "1px", borderColor: "border.strong", children: o2.value > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
62185
- /* @__PURE__ */ jsxRuntime.jsx(react.Box, { height: "12px", width: `${Math.round(upFrac * 100)}%`, bg: "fg.success", opacity: 0.6 }),
62186
- /* @__PURE__ */ jsxRuntime.jsx(react.Text, { fontSize: "10.5px", fontFamily: "mono", color: "fg.success", flexShrink: 0, children: fmt(decision, o2.value, true) })
62559
+ /* @__PURE__ */ jsxRuntime.jsx(react.Box, { height: "12px", width: `${Math.round(upFrac * 100)}%`, bg: signed2 ? "fg.success" : "fg.subtle", opacity: 0.6 }),
62560
+ /* @__PURE__ */ jsxRuntime.jsx(react.Text, { fontSize: "10.5px", fontFamily: "mono", color: signed2 ? "fg.success" : "fg.muted", flexShrink: 0, children: fmt(decision, o2.value, signed2) })
62187
62561
  ] }) })
62188
62562
  ]
62189
62563
  },
@@ -62368,7 +62742,8 @@ function useLeverPayloads(ref) {
62368
62742
  return (constraint == null ? void 0 : constraint.type) === "Variant" ? constraint.cases ?? {} : {};
62369
62743
  }, [ref, workspace]);
62370
62744
  }
62371
- const Row = React.memo(function Row2({ decision, handle, selected: selected2, narrow, leverPayloads, modify, detail, defaultFacet, apply: apply2, reject: reject2, leaving, storageKey }) {
62745
+ const Row = React.memo(function Row2({ decision, handle, selected: selected2, narrow, leverPayloads, modify, evidence, defaultFacet, facetInclude, apply: apply2, reject: reject2, leaving, storageKey }) {
62746
+ var _a2, _b2;
62372
62747
  const dq = react.useSlotRecipe({ key: "decisionQueue" });
62373
62748
  const status = react.useSlotRecipe({ key: "status" });
62374
62749
  const tabs = react.useSlotRecipe({ key: "facetTabs" });
@@ -62376,10 +62751,15 @@ const Row = React.memo(function Row2({ decision, handle, selected: selected2, na
62376
62751
  const rs = dq({});
62377
62752
  const ts = tabs({});
62378
62753
  const st = status({ status: URGENCY_TONE[decision.urgency.type], size: "md" });
62379
- const [facet, setFacet] = React.useState(defaultFacet);
62754
+ const visibleFacets = React.useMemo(
62755
+ () => FACETS.filter((f2) => f2.key === "modify" ? modify !== void 0 : facetInclude === null || facetInclude.has(f2.key)),
62756
+ [modify, facetInclude]
62757
+ );
62758
+ const effectiveDefault = visibleFacets.some((f2) => f2.key === defaultFacet) ? defaultFacet : ((_a2 = visibleFacets[0]) == null ? void 0 : _a2.key) ?? defaultFacet;
62759
+ const [facet, setFacet] = React.useState(effectiveDefault);
62380
62760
  React.useEffect(() => {
62381
- if (!selected2) setFacet(defaultFacet);
62382
- }, [selected2, defaultFacet]);
62761
+ if (!selected2) setFacet(effectiveDefault);
62762
+ }, [selected2, effectiveDefault]);
62383
62763
  const gate = handle.commitStateFor(decision.id);
62384
62764
  const applyEnabled = gate === null || gate.type === "ready";
62385
62765
  const gatePulse = !applyEnabled && decision.prompts.length > 0;
@@ -62398,10 +62778,10 @@ const Row = React.memo(function Row2({ decision, handle, selected: selected2, na
62398
62778
  return modify(decision, handle.update);
62399
62779
  }, [selected2, facet, modify, decision, handle.update]);
62400
62780
  const canvas = React.useMemo(() => {
62401
- if (!selected2 || facet !== "evidence" || !detail) return null;
62402
- return detail(decision);
62403
- }, [selected2, facet, detail, decision]);
62404
- const facetTabs = /* @__PURE__ */ jsxRuntime.jsx(react.Box, { css: ts.root, ...narrow ? { display: "flex", width: "100%" } : {}, children: FACETS.filter((f2) => f2.key !== "modify" || modify !== void 0).map((f2) => /* @__PURE__ */ jsxRuntime.jsx(
62781
+ if (!selected2 || facet !== "evidence" || !evidence) return null;
62782
+ return evidence(decision);
62783
+ }, [selected2, facet, evidence, decision]);
62784
+ const facetTabs = /* @__PURE__ */ jsxRuntime.jsx(react.Box, { css: ts.root, ...narrow ? { display: "flex", width: "100%" } : {}, children: visibleFacets.map((f2) => /* @__PURE__ */ jsxRuntime.jsx(
62405
62785
  react.Box,
62406
62786
  {
62407
62787
  as: "button",
@@ -62447,7 +62827,8 @@ const Row = React.memo(function Row2({ decision, handle, selected: selected2, na
62447
62827
  deadlineSuffix(decision)
62448
62828
  ] })
62449
62829
  ] });
62450
- const valueText = /* @__PURE__ */ jsxRuntime.jsx(react.Text, { fontFamily: "mono", fontWeight: "semibold", textAlign: "right", ...decision.value >= 0 && selected2 ? { color: "fg.success" } : {}, children: decisionValue(decision, decision.value, selected2) });
62830
+ const valueSigned = ((_b2 = eastUiComponents.getSomeorUndefined(decision.valueAxis)) == null ? void 0 : _b2.signed) ?? true;
62831
+ const valueText = /* @__PURE__ */ jsxRuntime.jsx(react.Text, { fontFamily: "mono", fontWeight: "semibold", textAlign: "right", ...valueSigned && decision.value >= 0 && selected2 ? { color: "fg.success" } : {}, children: decisionValue(decision, decision.value, valueSigned && selected2) });
62451
62832
  return /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { css: rs.rowShell, ...leaving ? { "data-leaving": leaving } : {}, children: [
62452
62833
  narrow ? /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { px: "14px", py: "10px", children: [
62453
62834
  /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { display: "flex", justifyContent: "space-between", alignItems: "baseline", children: [
@@ -62469,7 +62850,7 @@ const Row = React.memo(function Row2({ decision, handle, selected: selected2, na
62469
62850
  ] })
62470
62851
  ] }),
62471
62852
  selected2 && /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { px: narrow ? "14px" : "18px", py: "12px", borderTopWidth: "1px", borderColor: "border.subtle", bg: "bg.canvas", children: [
62472
- facet === "evidence" && /* @__PURE__ */ jsxRuntime.jsx(EvidenceFacet, { decision, children: canvas != null && /* @__PURE__ */ jsxRuntime.jsx(eastUiComponents.EastChakraComponent, { value: canvas, storageKey: `${storageKey}-detail-${decision.id}` }) }),
62853
+ facet === "evidence" && /* @__PURE__ */ jsxRuntime.jsx(EvidenceFacet, { decision, children: canvas != null && /* @__PURE__ */ jsxRuntime.jsx(eastUiComponents.EastChakraComponent, { value: canvas, storageKey: `${storageKey}-evidence-${decision.id}` }) }),
62473
62854
  facet === "options" && /* @__PURE__ */ jsxRuntime.jsx(OptionsFacet, { decision, narrow }),
62474
62855
  facet === "judgement" && /* @__PURE__ */ jsxRuntime.jsx(JudgementFacet, { decision, handle, leverPayloads }),
62475
62856
  facet === "modify" && probe != null && /* @__PURE__ */ jsxRuntime.jsx(eastUiComponents.EastChakraComponent, { value: probe, storageKey: `${storageKey}-modify-${decision.id}` })
@@ -62577,11 +62958,15 @@ const EastChakraDecisionQueue = React.memo(function EastChakraDecisionQueue2({ v
62577
62958
  () => eastUiComponents.getSomeorUndefined(value.modify),
62578
62959
  [value.modify]
62579
62960
  );
62580
- const detail = React.useMemo(
62581
- () => eastUiComponents.getSomeorUndefined(value.detail),
62582
- [value.detail]
62961
+ const evidence = React.useMemo(
62962
+ () => eastUiComponents.getSomeorUndefined(value.evidence),
62963
+ [value.evidence]
62583
62964
  );
62584
62965
  const defaultFacet = ((_a2 = eastUiComponents.getSomeorUndefined(value.defaultFacet)) == null ? void 0 : _a2.type) ?? "evidence";
62966
+ const facetInclude = React.useMemo(() => {
62967
+ const facets = eastUiComponents.getSomeorUndefined(value.facets);
62968
+ return facets === void 0 ? null : new Set(facets.map((f2) => f2.type));
62969
+ }, [value.facets]);
62585
62970
  const defaultExpanded = eastUiComponents.getSomeorUndefined(value.defaultExpanded);
62586
62971
  const selectedId = handle.selected ?? (defaultExpanded == null ? void 0 : defaultExpanded.id) ?? null;
62587
62972
  const resolve2 = React.useCallback((ds, hook2, reason) => {
@@ -62668,8 +63053,9 @@ const EastChakraDecisionQueue = React.memo(function EastChakraDecisionQueue2({ v
62668
63053
  narrow,
62669
63054
  leverPayloads,
62670
63055
  modify,
62671
- detail,
63056
+ evidence,
62672
63057
  defaultFacet,
63058
+ facetInclude,
62673
63059
  apply: apply2,
62674
63060
  reject: reject2,
62675
63061
  leaving: exitingReasons.get(d2.id),
@@ -62683,7 +63069,7 @@ const EastChakraDecisionQueue = React.memo(function EastChakraDecisionQueue2({ v
62683
63069
  )
62684
63070
  ] });
62685
63071
  });
62686
- eastUiComponents.implementUIComponent(internal.DecisionQueue.Component, EastChakraDecisionQueue);
63072
+ eastUiComponents.implementUIComponent(internal$1.DecisionQueue.Component, EastChakraDecisionQueue);
62687
63073
  function verdictPresentation(verdict) {
62688
63074
  switch (verdict.type) {
62689
63075
  case "accepted":
@@ -62787,7 +63173,7 @@ const EastChakraDecisionJournal = React.memo(function EastChakraDecisionJournal2
62787
63173
  )
62788
63174
  ] });
62789
63175
  });
62790
- eastUiComponents.implementUIComponent(internal.DecisionJournal.Component, EastChakraDecisionJournal);
63176
+ eastUiComponents.implementUIComponent(internal$1.DecisionJournal.Component, EastChakraDecisionJournal);
62791
63177
  function formatApiError(error3) {
62792
63178
  if (error3 instanceof e3ApiClient.ApiError && error3.details != null) {
62793
63179
  const details = error3.details;
@@ -63075,7 +63461,20 @@ function useDatasetStatus(apiUrl, repo, workspace, datasetPath, options2) {
63075
63461
  ...queryOverrides
63076
63462
  });
63077
63463
  }
63078
- const defaultPlatformImplementations = [...eastUiComponents.StateImpl, ...BindPlatform, ...eastUiComponents.OverlayImpl];
63464
+ const defaultPlatformImplementations = [
63465
+ ...eastUiComponents.StateImpl,
63466
+ ...eastUiComponents.NavImpl,
63467
+ ...eastUiComponents.SliceImpl,
63468
+ ...eastUiComponents.SliceApplyImpl,
63469
+ ...eastUiComponents.OverlayImpl,
63470
+ ...eastUiComponents.ClipboardImpl,
63471
+ ...eastUiComponents.DownloadImpl,
63472
+ ...eastUiComponents.ShareImpl,
63473
+ ...DecisionBindPlatform,
63474
+ ...BindPlatform,
63475
+ ...FuncPlatform,
63476
+ ...RecordPlatform
63477
+ ];
63079
63478
  function useDatasetValue(apiUrl, repo, workspace, datasetPath, options2) {
63080
63479
  const { requestOptions, queryOverrides, enabled = true, hash: hash2, platforms, type } = options2;
63081
63480
  const platformImpls = platforms ?? defaultPlatformImplementations;
@@ -63176,6 +63575,7 @@ function StatusDisplay({ variant, title, message, details }) {
63176
63575
  return /* @__PURE__ */ jsxRuntime.jsx(
63177
63576
  react.Box,
63178
63577
  {
63578
+ "data-status": variant,
63179
63579
  height: "100%",
63180
63580
  width: "100%",
63181
63581
  display: "flex",
@@ -63209,7 +63609,7 @@ function StatusDisplay({ variant, title, message, details }) {
63209
63609
  }
63210
63610
  );
63211
63611
  }
63212
- return /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { p: 6, bg: styles2.bg, height: "100%", width: "100%", children: [
63612
+ return /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { "data-status": variant, p: 6, bg: styles2.bg, height: "100%", width: "100%", children: [
63213
63613
  /* @__PURE__ */ jsxRuntime.jsx(react.Text, { fontSize: "lg", fontWeight: "bold", color: styles2.titleColor, mb: 4, children: title }),
63214
63614
  message && /* @__PURE__ */ jsxRuntime.jsx(react.Text, { color: styles2.messageColor, mb: details ? 4 : 0, children: message }),
63215
63615
  details && /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { position: "relative", children: [
@@ -63713,7 +64113,7 @@ const UITaskPreview = React.memo(function UITaskPreview2({
63713
64113
  const manifest = React.useMemo(() => {
63714
64114
  if (!details || !isUI) return null;
63715
64115
  const meta3 = getTaskMetadata(details);
63716
- return meta3 ? internal.decodeManifest(meta3) : { paths: [], functions: [], records: [] };
64116
+ return meta3 ? internal$1.decodeManifest(meta3) : { paths: [], functions: [], records: [] };
63717
64117
  }, [details, isUI]);
63718
64118
  const outputPath = details ? treePathToString$1(details.output) : null;
63719
64119
  const preloads = React.useMemo(
@@ -63723,11 +64123,22 @@ const UITaskPreview = React.memo(function UITaskPreview2({
63723
64123
  const { loading: preloading, error: preloadError } = usePreloadReactiveDatasets(preloads);
63724
64124
  const scopedPlatforms = React.useMemo(
63725
64125
  () => manifest ? [
64126
+ // EVERY browser-local platform impl (unscoped — no manifest paths) from east-ui-components +
64127
+ // e3-ui-components MUST be listed here, or a ui() task that uses it throws "Platform function
64128
+ // '<x>_bind' is not available" — and only inside an e3 ui() task, so component tests miss it
64129
+ // (see east-contribute "Common traps"). The manifest-SCOPED data/func/record binds follow.
63726
64130
  ...eastUiComponents.StateImpl,
64131
+ ...eastUiComponents.NavImpl,
64132
+ ...eastUiComponents.SliceImpl,
64133
+ ...eastUiComponents.SliceApplyImpl,
64134
+ ...eastUiComponents.OverlayImpl,
64135
+ ...eastUiComponents.ClipboardImpl,
64136
+ ...eastUiComponents.DownloadImpl,
64137
+ ...eastUiComponents.ShareImpl,
64138
+ ...DecisionBindPlatform,
63727
64139
  ...createScopedBindPlatform(manifest),
63728
64140
  ...createScopedFuncPlatform(manifest.functions),
63729
- ...createScopedRecordPlatform(manifest.records),
63730
- ...eastUiComponents.OverlayImpl
64141
+ ...createScopedRecordPlatform(manifest.records)
63731
64142
  ] : void 0,
63732
64143
  [manifest]
63733
64144
  );