@elaraai/e3-ui-components 1.0.26 → 1.0.28

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");
@@ -2882,10 +2883,10 @@ function clearStagedStoreSingleton() {
2882
2883
  }
2883
2884
  const UNCHANGED_VARIANT = east.variant("unchanged", null);
2884
2885
  const blobEqual = east.equalFor(east.BlobType);
2885
- const eastTypeEqual$2 = east.equalFor(internal$1.EastTypeType);
2886
+ const eastTypeEqual$2 = east.equalFor(internal.EastTypeType);
2886
2887
  const helpersCache = new east.SortedMap(
2887
2888
  void 0,
2888
- east.compareFor(internal$1.EastTypeType)
2889
+ east.compareFor(internal.EastTypeType)
2889
2890
  );
2890
2891
  function getBindingHelpers(sourceType) {
2891
2892
  let cached = helpersCache.get(sourceType);
@@ -2934,6 +2935,17 @@ class BindRuntime {
2934
2935
  __publicField(this, "fallbackWarningEmitted", /* @__PURE__ */ new Set());
2935
2936
  // List cache helpers.
2936
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
+ ));
2937
2949
  this.staged = staged;
2938
2950
  this.staged.onPersistError((_key, err) => this.emitWriteError(err));
2939
2951
  }
@@ -2964,6 +2976,7 @@ class BindRuntime {
2964
2976
  clearCache() {
2965
2977
  this.cache = null;
2966
2978
  this.clearPendingWrites();
2979
+ this.handleCache.clear();
2967
2980
  }
2968
2981
  // ----- pending writes queue -------------------------------------------
2969
2982
  /** Subscribe to write-queue errors. Returns an unsubscribe fn. */
@@ -3090,13 +3103,14 @@ class BindRuntime {
3090
3103
  }
3091
3104
  // ----- bind-handle construction --------------------------------------
3092
3105
  /**
3093
- * Build a bind handle for a single `(sourcePath, mode, patch?)`
3094
- * triple. Public so tests can call this directly without going
3095
- * 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.
3096
3111
  *
3097
- * @throws `EastError` if the cache is uninitialized, the
3098
- * workspace is not configured, or `allowed` is non-null and any
3099
- * 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.
3100
3114
  */
3101
3115
  buildBindHandle(sourceType, sourcePath, patchPath, mode, allowed) {
3102
3116
  const cache3 = this.requireCache();
@@ -3120,6 +3134,106 @@ class BindRuntime {
3120
3134
  }
3121
3135
  }
3122
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");
3123
3237
  const { patchType, decodeT, encodeT, decodePatch, encodePatch, apply: apply2, diff: diff2 } = getBindingHelpers(sourceType);
3124
3238
  this.registerBindingTypes(ws, sourcePath, {
3125
3239
  workspace: ws,
@@ -3359,7 +3473,7 @@ class BindRuntime {
3359
3473
  * Pass `allowed=null` for an unscoped impl (the global
3360
3474
  * `BindPlatform`); pass a Set for manifest scoping. */
3361
3475
  buildPlatform(allowed) {
3362
- return internal.bindPlatformFn.implement(
3476
+ return internal$1.bindPlatformFn.implement(
3363
3477
  (sourceType) => (sourcePathArg, patchOpt, modeVariant) => {
3364
3478
  const sourcePath = sourcePathArg;
3365
3479
  const { patchPath, mode } = resolveOptions(patchOpt, modeVariant);
@@ -3434,10 +3548,16 @@ function awaitPendingWrites() {
3434
3548
  function clearPendingWrites() {
3435
3549
  defaultBindRuntime.clearPendingWrites();
3436
3550
  }
3437
- const BindPlatform = [defaultBindRuntime.buildPlatform(null)];
3551
+ const BindPlatform = [
3552
+ defaultBindRuntime.buildPlatform(null),
3553
+ ...defaultBindRuntime.buildPrimitives()
3554
+ ];
3438
3555
  function createScopedBindPlatform(manifest) {
3439
3556
  const allowed = new Set(manifest.paths.map((p2) => datasetPathToString(p2)));
3440
- return [defaultBindRuntime.buildPlatform(allowed)];
3557
+ return [
3558
+ defaultBindRuntime.buildPlatform(allowed),
3559
+ ...defaultBindRuntime.buildPrimitives()
3560
+ ];
3441
3561
  }
3442
3562
  async function preloadReactiveDatasetList(workspace, path2) {
3443
3563
  return defaultBindRuntime.preloadList(workspace, path2);
@@ -3586,7 +3706,7 @@ function createDefaultFunctionApi(apiUrl, repo, getToken) {
3586
3706
  }
3587
3707
  };
3588
3708
  }
3589
- const eastTypeEqual$1 = east.equalFor(internal$1.EastTypeType);
3709
+ const eastTypeEqual$1 = east.equalFor(internal.EastTypeType);
3590
3710
  function signatureOfFuncHandleType(handleType) {
3591
3711
  var _a2, _b2;
3592
3712
  if (handleType.type !== "Struct") {
@@ -3667,6 +3787,11 @@ class FuncRuntime extends TrackedChannelStore {
3667
3787
  __publicField(this, "workspace", null);
3668
3788
  // Signature lists are fetched once per workspace and cached.
3669
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());
3670
3795
  }
3671
3796
  createEntry() {
3672
3797
  return { status: "idle", launchSeq: 0 };
@@ -3684,6 +3809,7 @@ class FuncRuntime extends TrackedChannelStore {
3684
3809
  this.workspace = null;
3685
3810
  this.clearChannels();
3686
3811
  this.signatureLists.clear();
3812
+ this.handleCache.clear();
3687
3813
  }
3688
3814
  /** The deployed signature list for a workspace (fetched once). */
3689
3815
  signatures(workspace) {
@@ -3787,9 +3913,15 @@ class FuncRuntime extends TrackedChannelStore {
3787
3913
  }
3788
3914
  })();
3789
3915
  }
3790
- /** Build the handle value for one `Func.bind` platform evaluation. */
3791
- buildHandle(handleType, name) {
3792
- 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() {
3793
3925
  const runtime = this;
3794
3926
  const resolveWorkspace = () => {
3795
3927
  if (!runtime.workspace) {
@@ -3797,49 +3929,98 @@ class FuncRuntime extends TrackedChannelStore {
3797
3929
  }
3798
3930
  return runtime.workspace;
3799
3931
  };
3800
- const channel = () => {
3932
+ const channel = (name) => {
3801
3933
  const key = funcChannelKey(resolveWorkspace(), name);
3802
3934
  return { key, entry: runtime.entry(key) };
3803
3935
  };
3804
- return {
3805
- call: (...args) => {
3806
- 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);
3807
3945
  return null;
3808
- },
3809
- read: () => {
3810
- const { key, entry } = channel();
3946
+ }),
3947
+ internal$1.FuncBindPrimitives.read.implement((_outputType) => (nameArg) => {
3948
+ const { key, entry } = channel(nameArg);
3811
3949
  runtime.track(key);
3812
3950
  return entry.result !== void 0 ? east.variant("some", entry.result) : east.variant("none", null);
3813
- },
3814
- status: () => {
3815
- const { key, entry } = channel();
3951
+ }),
3952
+ internal$1.FuncBindPrimitives.status.implement((nameArg) => {
3953
+ const { key, entry } = channel(nameArg);
3816
3954
  runtime.track(key);
3817
3955
  return east.variant(entry.status, null);
3818
- },
3819
- error: () => {
3820
- const { key, entry } = channel();
3956
+ }),
3957
+ internal$1.FuncBindPrimitives.error.implement((nameArg) => {
3958
+ const { key, entry } = channel(nameArg);
3821
3959
  runtime.track(key);
3822
3960
  return entry.status === "failed" && entry.error !== void 0 ? east.variant("some", entry.error) : east.variant("none", null);
3823
- },
3824
- pending: () => {
3825
- const { key, entry } = channel();
3961
+ }),
3962
+ internal$1.FuncBindPrimitives.pending.implement((nameArg) => {
3963
+ const { key, entry } = channel(nameArg);
3826
3964
  runtime.track(key);
3827
3965
  return entry.status === "running";
3828
- },
3829
- cancel: () => {
3830
- const { key } = channel();
3966
+ }),
3967
+ internal$1.FuncBindPrimitives.cancel.implement((nameArg) => {
3968
+ const { key } = channel(nameArg);
3831
3969
  runtime.cancelChannel(key);
3832
3970
  return null;
3833
- },
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),
3834
4013
  binding: { name }
3835
4014
  };
4015
+ this.handleCache.set(name, handle);
4016
+ return handle;
3836
4017
  }
3837
4018
  // ----- platform building -------------------------------------------------
3838
4019
  /** Build a `Func.bind` PlatformFunction bound to this runtime. Pass
3839
4020
  * `allowed=null` for an unscoped impl; pass a Set of function names
3840
4021
  * for manifest scoping. */
3841
4022
  buildPlatform(allowed) {
3842
- return internal.funcBindPlatformFn.implement(
4023
+ return internal$1.funcBindPlatformFn.implement(
3843
4024
  (handleType) => (nameArg) => {
3844
4025
  const name = nameArg;
3845
4026
  if (allowed && !allowed.has(name)) {
@@ -3859,9 +4040,15 @@ function initializeFunctionApi(api3, workspace) {
3859
4040
  function clearFunctionApi() {
3860
4041
  defaultFuncRuntime.clear();
3861
4042
  }
3862
- const FuncPlatform = [defaultFuncRuntime.buildPlatform(null)];
4043
+ const FuncPlatform = [
4044
+ defaultFuncRuntime.buildPlatform(null),
4045
+ ...defaultFuncRuntime.buildPrimitives()
4046
+ ];
3863
4047
  function createScopedFuncPlatform(functions2) {
3864
- return [defaultFuncRuntime.buildPlatform(new Set(functions2))];
4048
+ return [
4049
+ defaultFuncRuntime.buildPlatform(new Set(functions2)),
4050
+ ...defaultFuncRuntime.buildPrimitives()
4051
+ ];
3865
4052
  }
3866
4053
  function createInMemoryFunctionApi(functions2) {
3867
4054
  const defs2 = functions2.map((def) => ({
@@ -7586,7 +7773,7 @@ function createDefaultRecordApi(apiUrl, repo, getToken) {
7586
7773
  }
7587
7774
  };
7588
7775
  }
7589
- const eastTypeEqual = east.equalFor(internal$1.EastTypeType);
7776
+ const eastTypeEqual = east.equalFor(internal.EastTypeType);
7590
7777
  const RESERVED_MUTATE_FIELDS = /* @__PURE__ */ new Set(["pending", "status", "error", "cancel"]);
7591
7778
  function signatureOfRecordHandleType(handleType) {
7592
7779
  var _a2, _b2;
@@ -7671,6 +7858,12 @@ class RecordRuntime extends TrackedChannelStore {
7671
7858
  // otherwise spin); cleared on the next commit / on clear() so a later
7672
7859
  // mutation retries.
7673
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());
7674
7867
  }
7675
7868
  createEntry() {
7676
7869
  return { status: "idle", launchSeq: 0 };
@@ -7693,6 +7886,7 @@ class RecordRuntime extends TrackedChannelStore {
7693
7886
  this.histories.clear();
7694
7887
  this.historyInFlight.clear();
7695
7888
  this.historyFailed.clear();
7889
+ this.handleCache.clear();
7696
7890
  }
7697
7891
  resolveWorkspace() {
7698
7892
  if (!this.workspace) {
@@ -7811,96 +8005,170 @@ class RecordRuntime extends TrackedChannelStore {
7811
8005
  if (current && current.inflight === run) delete current.inflight;
7812
8006
  });
7813
8007
  }
7814
- /** Build the handle value for one `Record.bind` platform evaluation. */
7815
- buildHandle(handleType, name) {
7816
- const sig = signatureOfRecordHandleType(handleType);
7817
- 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() {
7818
8018
  const runtime = this;
7819
- const path2 = recordPath(name);
7820
8019
  const requireCache = () => {
7821
8020
  if (!runtime.cache) {
7822
8021
  throw new Error("Record.bind: no dataset cache configured — mount a provider first");
7823
8022
  }
7824
8023
  return runtime.cache;
7825
8024
  };
7826
- const mutate = {
7827
- 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;
7828
8047
  const ws = runtime.resolveWorkspace();
7829
8048
  const key = recordChannelKey(ws, name);
7830
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);
7831
8068
  return runtime.entry(key).status === "running";
7832
- },
7833
- status: () => {
8069
+ }),
8070
+ internal$1.RecordBindPrimitives.mutateStatus.implement((nameArg) => {
7834
8071
  const ws = runtime.resolveWorkspace();
7835
- const key = recordChannelKey(ws, name);
8072
+ const key = recordChannelKey(ws, nameArg);
7836
8073
  runtime.track(key);
7837
8074
  return east.variant(runtime.entry(key).status, null);
7838
- },
7839
- error: () => {
8075
+ }),
8076
+ internal$1.RecordBindPrimitives.mutateError.implement((nameArg) => {
7840
8077
  const ws = runtime.resolveWorkspace();
7841
- const key = recordChannelKey(ws, name);
8078
+ const key = recordChannelKey(ws, nameArg);
7842
8079
  runtime.track(key);
7843
8080
  const entry = runtime.entry(key);
7844
8081
  return entry.status === "failed" && entry.error !== void 0 ? east.some(entry.error) : east.none;
7845
- },
7846
- cancel: () => {
8082
+ }),
8083
+ internal$1.RecordBindPrimitives.mutateCancel.implement((nameArg) => {
7847
8084
  const ws = runtime.resolveWorkspace();
7848
- runtime.cancelChannel(recordChannelKey(ws, name), (e3) => {
8085
+ runtime.cancelChannel(recordChannelKey(ws, nameArg), (e3) => {
7849
8086
  delete e3.error;
7850
8087
  delete e3.inflight;
7851
8088
  });
7852
8089
  return null;
7853
- }
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)
7854
8134
  };
7855
8135
  for (const [mutationName, argTypes] of sig.mutations) {
7856
- mutate[mutationName] = (...args) => {
7857
- runtime.launchMutation(runtime.resolveWorkspace(), name, mutationName, argTypes, args);
7858
- return null;
7859
- };
7860
- }
7861
- return {
7862
- read: () => {
7863
- const ws = runtime.resolveWorkspace();
7864
- trackDatasetPath(ws, path2);
7865
- const bytes = requireCache().read(ws, path2);
7866
- if (bytes === void 0) {
7867
- throw new Error(`Record.bind: record state not loaded: ${datasetCacheKey(ws, path2)} (it should be preloaded via the UI task manifest)`);
7868
- }
7869
- return decodeState(bytes);
7870
- },
7871
- status: () => {
7872
- const ws = runtime.resolveWorkspace();
7873
- trackDatasetPath(ws, path2);
7874
- return requireCache().getStatus(ws, path2);
7875
- },
7876
- history: () => {
7877
- const ws = runtime.resolveWorkspace();
7878
- const key = recordChannelKey(ws, name);
7879
- runtime.track(key);
7880
- const cached = runtime.histories.get(key);
7881
- if (cached === void 0) {
7882
- if (!runtime.historyFailed.has(key)) runtime.fetchHistory(ws, name, key);
7883
- return east.none;
7884
- }
7885
- return east.some(cached);
7886
- },
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),
7887
8157
  mutate,
7888
- start: () => {
7889
- const ws = runtime.resolveWorkspace();
7890
- const cache3 = requireCache();
7891
- const inflight = runtime.entry(recordChannelKey(ws, name)).inflight;
7892
- void Promise.resolve(inflight).catch(() => void 0).then(() => cache3.launchDataflow(ws)).catch(() => void 0);
7893
- return null;
7894
- },
8158
+ start: east.East.compile(east.East.function([], east.NullType, ($3) => {
8159
+ $3.return(P2.start(nameExpr));
8160
+ }), platform2),
7895
8161
  binding: { name, mutations: [...sig.mutations.keys()] }
7896
8162
  };
8163
+ this.handleCache.set(name, handle);
8164
+ return handle;
7897
8165
  }
7898
8166
  // ----- platform building -------------------------------------------------
7899
8167
  /** Build a `Record.bind` PlatformFunction bound to this runtime. Pass
7900
8168
  * `allowed=null` for an unscoped impl; pass a Set of record names for
7901
8169
  * manifest scoping. */
7902
8170
  buildPlatform(allowed) {
7903
- return internal.recordBindPlatformFn.implement(
8171
+ return internal$1.recordBindPlatformFn.implement(
7904
8172
  (handleType) => (nameArg) => {
7905
8173
  const name = nameArg;
7906
8174
  if (allowed && !allowed.has(name)) {
@@ -7920,9 +8188,15 @@ function initializeRecordApi(api3, cache3, workspace) {
7920
8188
  function clearRecordApi() {
7921
8189
  defaultRecordRuntime.clear();
7922
8190
  }
7923
- const RecordPlatform = [defaultRecordRuntime.buildPlatform(null)];
8191
+ const RecordPlatform = [
8192
+ defaultRecordRuntime.buildPlatform(null),
8193
+ ...defaultRecordRuntime.buildPrimitives()
8194
+ ];
7924
8195
  function createScopedRecordPlatform(records) {
7925
- return [defaultRecordRuntime.buildPlatform(new Set(records))];
8196
+ return [
8197
+ defaultRecordRuntime.buildPlatform(new Set(records)),
8198
+ ...defaultRecordRuntime.buildPrimitives()
8199
+ ];
7926
8200
  }
7927
8201
  function createInMemoryRecordApi(cache3, workspace, defs2) {
7928
8202
  const compiled = /* @__PURE__ */ new Map();
@@ -8351,7 +8625,7 @@ function parseManualDraft(leafType, draft) {
8351
8625
  return { ok: false };
8352
8626
  }
8353
8627
  }
8354
- const diffValueEqual = east.equalFor(internal.Diff.Component.schema);
8628
+ const diffValueEqual = east.equalFor(internal$1.Diff.Component.schema);
8355
8629
  function getOpt$1(opt) {
8356
8630
  return opt.type === "some" ? opt.value : void 0;
8357
8631
  }
@@ -9200,7 +9474,7 @@ const EastChakraDiff = React.memo(function EastChakraDiff2({ value }) {
9200
9474
  return /* @__PURE__ */ jsxRuntime.jsx(
9201
9475
  react.Box,
9202
9476
  {
9203
- layerStyle: "frame",
9477
+ layerStyle: "surface.frameless",
9204
9478
  p: "28px",
9205
9479
  textAlign: "center",
9206
9480
  color: "fg.subtle",
@@ -9227,9 +9501,8 @@ const EastChakraDiff = React.memo(function EastChakraDiff2({ value }) {
9227
9501
  return /* @__PURE__ */ jsxRuntime.jsxs(
9228
9502
  react.Box,
9229
9503
  {
9230
- layerStyle: "frame",
9504
+ layerStyle: "surface.frameless",
9231
9505
  fontFamily: "body",
9232
- borderColor: inConflictMode ? "fg.warning" : "border.strong",
9233
9506
  children: [
9234
9507
  /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { css: es.root, children: [
9235
9508
  /* @__PURE__ */ jsxRuntime.jsx(react.Box, { css: es.lbl, children: "Pending changes" }),
@@ -9339,7 +9612,7 @@ const EastChakraDiff = React.memo(function EastChakraDiff2({ value }) {
9339
9612
  function rowKey(pathStr, leafPath) {
9340
9613
  return `${pathStr}::${leafPath}`;
9341
9614
  }
9342
- eastUiComponents.implementUIComponent(internal.Diff.Component, EastChakraDiff);
9615
+ eastUiComponents.implementUIComponent(internal$1.Diff.Component, EastChakraDiff);
9343
9616
  function cc(names) {
9344
9617
  if (typeof names === "string" || typeof names === "number") return "" + names;
9345
9618
  let out = "";
@@ -57250,7 +57523,7 @@ const EastChakraOntology = React.memo(function EastChakraOntology2({ value }) {
57250
57523
  }
57251
57524
  );
57252
57525
  });
57253
- eastUiComponents.implementUIComponent(internal.Ontology.Component, EastChakraOntology);
57526
+ eastUiComponents.implementUIComponent(internal$1.Ontology.Component, EastChakraOntology);
57254
57527
  const EMPTY_PATH = [];
57255
57528
  function useBindingVersion(workspace, sourcePath, patchPath) {
57256
57529
  const staged = getStagedStore();
@@ -57317,7 +57590,7 @@ function useFuncCall(name, inputs, output2) {
57317
57590
  );
57318
57591
  const handle = React.useMemo(() => {
57319
57592
  if (!ready4) return null;
57320
- const handleType = east.toEastTypeValue(internal.FuncBindHandleType(inputs, output2));
57593
+ const handleType = east.toEastTypeValue(internal$1.FuncBindHandleType(inputs, output2));
57321
57594
  return defaultFuncRuntime.buildHandle(handleType, name);
57322
57595
  }, [ready4, name, workspace, sigKey]);
57323
57596
  const channelKey = ready4 ? funcChannelKey(workspace, name) : "";
@@ -60748,7 +61021,7 @@ function LoadingSkeleton() {
60748
61021
  const sk = react.useRecipe({ key: "skeleton" });
60749
61022
  const line2 = (w2, h2) => /* @__PURE__ */ jsxRuntime.jsx(react.Box, { css: sk({ variant: "line" }), width: w2, height: h2 });
60750
61023
  const block = (h2) => /* @__PURE__ */ jsxRuntime.jsx(react.Box, { css: sk({ variant: "block" }), width: "100%", minHeight: h2 });
60751
- return /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { layerStyle: "frame", overflow: "visible", children: [
61024
+ return /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { layerStyle: "surface.frameless", overflow: "visible", children: [
60752
61025
  /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { layerStyle: "header.bar", display: "flex", alignItems: "center", gap: "3.5", children: [
60753
61026
  line2("260px", "20px"),
60754
61027
  /* @__PURE__ */ jsxRuntime.jsx(react.Box, { flex: "1" }),
@@ -60763,7 +61036,7 @@ function LoadingSkeleton() {
60763
61036
  ] })
60764
61037
  ] });
60765
61038
  }
60766
- const experimentValueEqual = east.equalFor(internal.Experiment.Component.schema);
61039
+ const experimentValueEqual = east.equalFor(internal$1.Experiment.Component.schema);
60767
61040
  const EastChakraExperiment = React.memo(function EastChakraExperiment2({ value }) {
60768
61041
  var _a2, _b2, _c2;
60769
61042
  const v3 = value;
@@ -60832,16 +61105,16 @@ const EastChakraExperiment = React.memo(function EastChakraExperiment2({ value }
60832
61105
  }),
60833
61106
  [columns, meta3]
60834
61107
  );
60835
- const estInputs = React.useMemo(() => rowArrayType ? [rowArrayType, internal.Experiment.Types.Config] : null, [rowArrayType]);
60836
- const experiment = useFuncCall(v3.experiment.type === "some" ? v3.experiment.value.name : null, estInputs, internal.Experiment.Types.Result);
61108
+ const estInputs = React.useMemo(() => rowArrayType ? [rowArrayType, internal$1.Experiment.Types.Config] : null, [rowArrayType]);
61109
+ const experiment = useFuncCall(v3.experiment.type === "some" ? v3.experiment.value.name : null, estInputs, internal$1.Experiment.Types.Result);
60837
61110
  const hasExperiment = v3.experiment.type === "some";
60838
61111
  const shownResult = experiment.result ?? eastUiComponents.getSomeorUndefined(selectedEntry == null ? void 0 : selectedEntry.result) ?? null;
60839
61112
  const hasDesign = v3.design.type === "some";
60840
61113
  const designInputs = React.useMemo(
60841
- () => rowArrayType ? [rowArrayType, internal.Experiment.Types.Config, internal.Experiment.Types.Result, internal.Experiment.Types.DesignConfig] : null,
61114
+ () => rowArrayType ? [rowArrayType, internal$1.Experiment.Types.Config, internal$1.Experiment.Types.Result, internal$1.Experiment.Types.DesignConfig] : null,
60842
61115
  [rowArrayType]
60843
61116
  );
60844
- const design = useFuncCall(v3.design.type === "some" ? v3.design.value.name : null, designInputs, internal.Experiment.Types.Design);
61117
+ const design = useFuncCall(v3.design.type === "some" ? v3.design.value.name : null, designInputs, internal$1.Experiment.Types.Design);
60845
61118
  const pendingConfigRef = React.useRef(null);
60846
61119
  const [ranConfig, setRanConfig] = React.useState(null);
60847
61120
  const runAll = React.useCallback(() => {
@@ -60950,14 +61223,14 @@ const EastChakraExperiment = React.memo(function EastChakraExperiment2({ value }
60950
61223
  const which = data4.error ? "dataset" : configsBind.error ? "configs" : journalBind.error ? "journal" : null;
60951
61224
  const bindError = data4.error ?? configsBind.error ?? journalBind.error;
60952
61225
  const bindMsg = bindError instanceof Error ? bindError.message : bindError != null ? String(bindError) : null;
60953
- if (bindMsg) return /* @__PURE__ */ jsxRuntime.jsx(react.Box, { layerStyle: "frame", p: "6", children: /* @__PURE__ */ jsxRuntime.jsxs(react.Text, { textStyle: "body.sm", color: "fg.danger", children: [
61226
+ if (bindMsg) return /* @__PURE__ */ jsxRuntime.jsx(react.Box, { layerStyle: "surface.frameless", p: "6", children: /* @__PURE__ */ jsxRuntime.jsxs(react.Text, { textStyle: "body.sm", color: "fg.danger", children: [
60954
61227
  "Couldn’t load the experiment ",
60955
61228
  which,
60956
61229
  ": ",
60957
61230
  bindMsg
60958
61231
  ] }) });
60959
- if (noConfigs) return /* @__PURE__ */ jsxRuntime.jsx(react.Box, { layerStyle: "frame", p: "6", children: /* @__PURE__ */ jsxRuntime.jsx(react.Text, { textStyle: "body.sm", color: "fg.muted", children: "No questions to show — bind a non-empty configs list." }) });
60960
- if (failed2 && experiment.error) return /* @__PURE__ */ jsxRuntime.jsx(react.Box, { layerStyle: "frame", p: "6", children: /* @__PURE__ */ jsxRuntime.jsx(RunError, { error: experiment.error }) });
61232
+ if (noConfigs) return /* @__PURE__ */ jsxRuntime.jsx(react.Box, { layerStyle: "surface.frameless", p: "6", children: /* @__PURE__ */ jsxRuntime.jsx(react.Text, { textStyle: "body.sm", color: "fg.muted", children: "No questions to show — bind a non-empty configs list." }) });
61233
+ if (failed2 && experiment.error) return /* @__PURE__ */ jsxRuntime.jsx(react.Box, { layerStyle: "surface.frameless", p: "6", children: /* @__PURE__ */ jsxRuntime.jsx(RunError, { error: experiment.error }) });
60961
61234
  return /* @__PURE__ */ jsxRuntime.jsx(LoadingSkeleton, {});
60962
61235
  }
60963
61236
  const { spec: vs, answer: a2, refusal: ref, overlap: ov, refute: vr, dose: vd, journal, verdict } = view;
@@ -60978,7 +61251,7 @@ const EastChakraExperiment = React.memo(function EastChakraExperiment2({ value }
60978
61251
  const anyPrecomputedDesign = configs.some((c2) => c2.design.type === "some");
60979
61252
  const showValidate = hasDesign || anyPrecomputedDesign;
60980
61253
  const tabKeys = [...["answer", "trust", "dose"], ...showValidate ? ["validate"] : []];
60981
- return /* @__PURE__ */ jsxRuntime.jsx(GuidanceProvider, { on: guidance, vars: helpVars, children: /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { layerStyle: "frame", overflow: "visible", children: [
61254
+ return /* @__PURE__ */ jsxRuntime.jsx(GuidanceProvider, { on: guidance, vars: helpVars, children: /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { layerStyle: "surface.frameless", overflow: "visible", children: [
60982
61255
  /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { layerStyle: "header.bar", display: "flex", alignItems: "center", gap: "3.5", children: [
60983
61256
  configs.length > 1 ? /* @__PURE__ */ jsxRuntime.jsxs(react.Menu.Root, { children: [
60984
61257
  /* @__PURE__ */ jsxRuntime.jsx(react.Menu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { as: "button", bg: "transparent", border: "0", p: "0", cursor: "pointer", display: "inline-flex", alignItems: "center", gap: "2", textAlign: "start", children: [
@@ -61582,7 +61855,7 @@ function Segmented({ label, left, right, active, onPick, last: last2, help, read
61582
61855
  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" })
61583
61856
  ] });
61584
61857
  }
61585
- eastUiComponents.implementUIComponent(internal.Experiment.Component, EastChakraExperiment);
61858
+ eastUiComponents.implementUIComponent(internal$1.Experiment.Component, EastChakraExperiment);
61586
61859
  const SELECTION_TYPE = east.OptionType(east.StringType);
61587
61860
  const encodeSelection = east.encodeBeast2For(SELECTION_TYPE);
61588
61861
  const decodeSelection = east.decodeBeast2For(SELECTION_TYPE);
@@ -61630,23 +61903,23 @@ function hashString2(s2) {
61630
61903
  for (let i = 0; i < s2.length; i++) h2 = (h2 << 5) + h2 + s2.charCodeAt(i) | 0;
61631
61904
  return (h2 >>> 0).toString(36);
61632
61905
  }
61633
- function buildDecisionHandle(decisions, judgements, sliceInit) {
61634
- const selectionKey = deriveSelectionKey(decisions);
61635
- const readSelection = () => {
61636
- eastUiComponents.StateRuntime.trackKey(selectionKey);
61637
- const bytes = eastUiComponents.StateRuntime.getStore().read(selectionKey);
61638
- return bytes === void 0 ? east.none : decodeSelection(bytes);
61639
- };
61640
- const writeSelection = (value) => {
61641
- eastUiComponents.StateRuntime.getStore().write(selectionKey, encodeSelection(value));
61642
- return null;
61643
- };
61644
- const queue = () => decisions.flatMap((b2) => viewFor(b2).read());
61645
- const readJudgements = () => viewFor(judgements).read();
61646
- const writeJudgements = (next2) => {
61647
- viewFor(judgements).write(next2);
61648
- };
61649
- const judgementFor = (caseId) => readJudgements().get(caseId) ?? {
61906
+ function readSelectionAt(selectionKey) {
61907
+ platform.StateRuntime.trackKey(selectionKey);
61908
+ const bytes = platform.StateRuntime.getStore().read(selectionKey);
61909
+ return bytes === void 0 ? east.none : decodeSelection(bytes);
61910
+ }
61911
+ function writeSelectionAt(selectionKey, value) {
61912
+ platform.StateRuntime.getStore().write(selectionKey, encodeSelection(value));
61913
+ return null;
61914
+ }
61915
+ function hostQueue(decisions) {
61916
+ return decisions.flatMap((b2) => viewFor(b2).read());
61917
+ }
61918
+ function readJudgementsAt(judgements) {
61919
+ return viewFor(judgements).read();
61920
+ }
61921
+ function judgementForAt(judgements, caseId) {
61922
+ return readJudgementsAt(judgements).get(caseId) ?? {
61650
61923
  caseId,
61651
61924
  answers: /* @__PURE__ */ new Map(),
61652
61925
  knowledge: east.none,
@@ -61654,105 +61927,194 @@ function buildDecisionHandle(decisions, judgements, sliceInit) {
61654
61927
  verdict: east.none,
61655
61928
  resolvedAt: east.none
61656
61929
  };
61657
- const stageJudgement = (caseId, change) => {
61658
- const dict = new Map(readJudgements());
61659
- dict.set(caseId, { ...judgementFor(caseId), ...change });
61660
- writeJudgements(dict);
61661
- return null;
61662
- };
61663
- const removeFromOwningView = (caseId) => {
61664
- for (const binding of decisions) {
61665
- const view = viewFor(binding);
61666
- const rows = view.read();
61667
- if (rows.some((d2) => d2.id === caseId)) {
61668
- view.write(rows.filter((d2) => d2.id !== caseId));
61669
- }
61930
+ }
61931
+ function stageJudgementAt(judgements, caseId, change) {
61932
+ const dict = new Map(readJudgementsAt(judgements));
61933
+ dict.set(caseId, { ...judgementForAt(judgements, caseId), ...change });
61934
+ viewFor(judgements).write(dict);
61935
+ return null;
61936
+ }
61937
+ function removeFromOwningView(decisions, caseId) {
61938
+ for (const binding of decisions) {
61939
+ const view = viewFor(binding);
61940
+ const rows = view.read();
61941
+ if (rows.some((d2) => d2.id === caseId)) {
61942
+ view.write(rows.filter((d2) => d2.id !== caseId));
61670
61943
  }
61671
- };
61672
- const slice3 = eastUiComponents.buildSliceHandle(
61944
+ }
61945
+ }
61946
+ const decisionHandleCache = /* @__PURE__ */ new Map();
61947
+ function typeToken(tv) {
61948
+ const seen = /* @__PURE__ */ new WeakSet();
61949
+ return JSON.stringify(tv, (_k, v3) => {
61950
+ if (typeof v3 === "object" && v3 !== null) {
61951
+ if (seen.has(v3)) return "<cyc>";
61952
+ seen.add(v3);
61953
+ }
61954
+ return typeof v3 === "bigint" ? `${v3}n` : v3;
61955
+ });
61956
+ }
61957
+ function compileDecisionMethods(constraintType, decisions, judgements, selectionKey) {
61958
+ const platform$1 = platform.getRegisteredPlatformImplementations();
61959
+ const c2 = east.fromEastTypeValue(constraintType);
61960
+ const decisionsExpr = east.East.value(decisions, east.ArrayType(internal$1.DiffBindingType));
61961
+ const judgementsExpr = east.East.value(judgements, internal$1.DiffBindingType);
61962
+ const selKeyExpr = east.East.value(selectionKey, east.StringType);
61963
+ const {
61964
+ queue,
61965
+ selected: selected2,
61966
+ select: select2,
61967
+ clearSelection,
61968
+ decision,
61969
+ update: update2,
61970
+ judgement,
61971
+ answer,
61972
+ addKnowledge,
61973
+ inject,
61974
+ resolve: resolve2,
61975
+ commitState
61976
+ } = internal$1.DecisionBindPrimitives;
61977
+ return {
61978
+ queue: east.East.compile(east.East.function([], east.ArrayType(internal$1.DecisionType), ($3) => {
61979
+ $3.return(queue(decisionsExpr));
61980
+ }), platform$1),
61981
+ selected: east.East.compile(east.East.function([], east.OptionType(east.StringType), ($3) => {
61982
+ $3.return(selected2(selKeyExpr));
61983
+ }), platform$1),
61984
+ select: east.East.compile(east.East.function([east.StringType], east.NullType, ($3, id3) => {
61985
+ $3.return(select2(selKeyExpr, id3));
61986
+ }), platform$1),
61987
+ clearSelection: east.East.compile(east.East.function([], east.NullType, ($3) => {
61988
+ $3.return(clearSelection(selKeyExpr));
61989
+ }), platform$1),
61990
+ decision: east.East.compile(east.East.function([], east.OptionType(internal$1.DecisionType), ($3) => {
61991
+ $3.return(decision(decisionsExpr, selKeyExpr));
61992
+ }), platform$1),
61993
+ update: east.East.compile(east.East.function([internal$1.DecisionType], east.NullType, ($3, edited) => {
61994
+ $3.return(update2(decisionsExpr, edited));
61995
+ }), platform$1),
61996
+ judgement: east.East.compile(east.East.function([east.StringType], internal$1.judgementInputType(c2), ($3, id3) => {
61997
+ $3.return(judgement([c2], judgementsExpr, id3));
61998
+ }), platform$1),
61999
+ answer: east.East.compile(east.East.function([east.StringType, east.StringType, internal$1.AnswerType], east.NullType, ($3, id3, prompt, ans) => {
62000
+ $3.return(answer(judgementsExpr, id3, prompt, ans));
62001
+ }), platform$1),
62002
+ addKnowledge: east.East.compile(east.East.function([east.StringType, east.StringType], east.NullType, ($3, id3, text) => {
62003
+ $3.return(addKnowledge(judgementsExpr, id3, text));
62004
+ }), platform$1),
62005
+ inject: east.East.compile(east.East.function([east.StringType, c2], east.NullType, ($3, id3, con) => {
62006
+ $3.return(inject([c2], judgementsExpr, id3, con));
62007
+ }), platform$1),
62008
+ resolve: east.East.compile(east.East.function([east.StringType, internal$1.VerdictType], east.NullType, ($3, id3, verdict) => {
62009
+ $3.return(resolve2(decisionsExpr, judgementsExpr, selKeyExpr, id3, verdict));
62010
+ }), platform$1),
62011
+ commitState: east.East.compile(east.East.function([east.StringType], internal$1.CommitStateType, ($3, id3) => {
62012
+ $3.return(commitState(decisionsExpr, judgementsExpr, id3));
62013
+ }), platform$1)
62014
+ };
62015
+ }
62016
+ function buildDecisionHandle(decisions, judgements, sliceInit, constraintType) {
62017
+ const cType = constraintType ?? east.toEastTypeValue(internal$1.DecisionConstraintType);
62018
+ const selectionKey = deriveSelectionKey(decisions);
62019
+ const slice3 = platform.buildSliceHandle(
61673
62020
  deriveSliceKey(decisions, sliceInit),
61674
62021
  DECISION_SLICE_CONFIG,
61675
- sliceInit ?? eastUiComponents.DEFAULT_SLICE_STATE,
61676
- () => queue(),
62022
+ sliceInit ?? platform.DEFAULT_SLICE_STATE,
62023
+ () => hostQueue(decisions),
61677
62024
  east.none
61678
62025
  );
62026
+ const journal = () => {
62027
+ const entries = [...readJudgementsAt(judgements).values()].filter((j2) => j2.verdict.type === "some");
62028
+ const at = (j2) => j2.resolvedAt.type === "some" ? j2.resolvedAt.value.getTime() : 0;
62029
+ return entries.sort((a2, b2) => at(b2) - at(a2));
62030
+ };
62031
+ const cacheKey = `${hashString2(stableStringify({ decisions, judgements }))}|${typeToken(cType)}`;
62032
+ let methods = decisionHandleCache.get(cacheKey);
62033
+ if (methods === void 0) {
62034
+ methods = compileDecisionMethods(cType, decisions, judgements, selectionKey);
62035
+ decisionHandleCache.set(cacheKey, methods);
62036
+ }
61679
62037
  return {
61680
62038
  decisions,
61681
62039
  judgements,
61682
62040
  sliceInit: sliceInit !== void 0 ? east.some(sliceInit) : east.none,
61683
62041
  slice: slice3,
61684
- queue,
61685
- selected: readSelection,
61686
- select: (caseId) => writeSelection(east.some(caseId)),
61687
- clearSelection: () => writeSelection(east.none),
61688
- decision: () => {
61689
- const selection2 = readSelection();
61690
- if (selection2.type === "none") return east.none;
61691
- const found = queue().find((d2) => d2.id === selection2.value);
61692
- return found === void 0 ? east.none : east.some(found);
61693
- },
61694
- update: (edited) => {
61695
- for (const binding of decisions) {
61696
- const view = viewFor(binding);
61697
- const rows = view.read();
61698
- if (rows.some((d2) => d2.id === edited.id)) {
61699
- view.write(rows.map((d2) => d2.id === edited.id ? edited : d2));
61700
- }
61701
- }
61702
- return null;
61703
- },
61704
- judgement: judgementFor,
61705
- answer: (caseId, prompt, response) => {
61706
- const answers = new Map(judgementFor(caseId).answers);
61707
- answers.set(prompt, response);
61708
- return stageJudgement(caseId, { answers });
61709
- },
61710
- addKnowledge: (caseId, text) => stageJudgement(caseId, { knowledge: east.some(text) }),
61711
- inject: (caseId, constraint) => {
61712
- const constraints = judgementFor(caseId).constraints.filter((c2) => c2.type !== constraint.type).concat([constraint]);
61713
- return stageJudgement(caseId, { constraints });
61714
- },
61715
- resolve: (caseId, verdict) => {
61716
- stageJudgement(caseId, { verdict: east.some(verdict), resolvedAt: east.some(/* @__PURE__ */ new Date()) });
61717
- removeFromOwningView(caseId);
61718
- writeSelection(east.none);
61719
- return null;
61720
- },
61721
- journal: () => {
61722
- const entries = [...readJudgements().values()].filter((j2) => j2.verdict.type === "some");
61723
- const at = (j2) => j2.resolvedAt.type === "some" ? j2.resolvedAt.value.getTime() : 0;
61724
- return entries.sort((a2, b2) => at(b2) - at(a2));
61725
- },
61726
- commitState: (caseId) => {
61727
- const decision = queue().find((d2) => d2.id === caseId);
61728
- const prompts = (decision == null ? void 0 : decision.prompts) ?? [];
61729
- const answers = judgementFor(caseId).answers;
61730
- const responses = prompts.map((p2) => {
61731
- var _a2;
61732
- return (_a2 = answers.get(p2.id)) == null ? void 0 : _a2.type;
61733
- });
61734
- if (responses.some((r2) => r2 === "no")) return east.variant("blocked", null);
61735
- if (responses.some((r2) => r2 === "unknown")) return east.variant("handoff", null);
61736
- const unanswered = responses.filter((r2) => r2 === void 0).length;
61737
- if (unanswered > 0) return east.variant("gated", BigInt(unanswered));
61738
- return east.variant("ready", null);
61739
- }
62042
+ journal,
62043
+ ...methods
61740
62044
  };
61741
62045
  }
61742
62046
  const DecisionBindPlatform = [
61743
- // Generic over the constraint contract — the type argument resolver
61744
- // receives the contract type value; the JS impl is type-agnostic.
61745
- internal.decisionBindPlatformFn.implement((_constraintType) => (decisionsArg, judgementsArg, sliceInitArg) => buildDecisionHandle(
62047
+ // Generic over the constraint contract — the resolver receives the contract
62048
+ // type value and threads it into the IR-bearing judgement / inject methods.
62049
+ internal$1.decisionBindPlatformFn.implement((constraintType) => (decisionsArg, judgementsArg, sliceInitArg) => buildDecisionHandle(
61746
62050
  decisionsArg,
61747
62051
  judgementsArg,
61748
- eastUiComponents.getSomeorUndefined(sliceInitArg)
61749
- ))
62052
+ platform.getSomeorUndefined(sliceInitArg),
62053
+ constraintType
62054
+ )),
62055
+ // ── issue #106 primitives — host I/O backing the IR-bearing handle methods.
62056
+ // Each is a faithful lift of the original closure body, taking the plain-data
62057
+ // descriptor(s) + the selection key as arguments. ──
62058
+ internal$1.DecisionBindPrimitives.queue.implement((decisions) => hostQueue(decisions)),
62059
+ internal$1.DecisionBindPrimitives.selected.implement((selectionKey) => readSelectionAt(selectionKey)),
62060
+ internal$1.DecisionBindPrimitives.select.implement((selectionKey, caseId) => writeSelectionAt(selectionKey, east.some(caseId))),
62061
+ internal$1.DecisionBindPrimitives.clearSelection.implement((selectionKey) => writeSelectionAt(selectionKey, east.none)),
62062
+ internal$1.DecisionBindPrimitives.decision.implement((decisions, selectionKey) => {
62063
+ const sel = readSelectionAt(selectionKey);
62064
+ if (sel.type === "none") return east.none;
62065
+ const found = hostQueue(decisions).find((d2) => d2.id === sel.value);
62066
+ return found === void 0 ? east.none : east.some(found);
62067
+ }),
62068
+ internal$1.DecisionBindPrimitives.update.implement((decisions, edited) => {
62069
+ const e3 = edited;
62070
+ for (const binding of decisions) {
62071
+ const view = viewFor(binding);
62072
+ const rows = view.read();
62073
+ if (rows.some((d2) => d2.id === e3.id)) {
62074
+ view.write(rows.map((d2) => d2.id === e3.id ? e3 : d2));
62075
+ }
62076
+ }
62077
+ return null;
62078
+ }),
62079
+ internal$1.DecisionBindPrimitives.judgement.implement((_c2) => (judgements, caseId) => judgementForAt(judgements, caseId)),
62080
+ internal$1.DecisionBindPrimitives.answer.implement((judgements, caseId, prompt, response) => {
62081
+ const answers = new Map(judgementForAt(judgements, caseId).answers);
62082
+ answers.set(prompt, response);
62083
+ return stageJudgementAt(judgements, caseId, { answers });
62084
+ }),
62085
+ internal$1.DecisionBindPrimitives.addKnowledge.implement((judgements, caseId, text) => stageJudgementAt(judgements, caseId, { knowledge: east.some(text) })),
62086
+ internal$1.DecisionBindPrimitives.inject.implement((_c2) => (judgements, caseId, constraint) => {
62087
+ const con = constraint;
62088
+ const constraints = judgementForAt(judgements, caseId).constraints.filter((x2) => x2.type !== con.type).concat([con]);
62089
+ return stageJudgementAt(judgements, caseId, { constraints });
62090
+ }),
62091
+ internal$1.DecisionBindPrimitives.resolve.implement((decisions, judgements, selectionKey, caseId, verdict) => {
62092
+ stageJudgementAt(judgements, caseId, { verdict: east.some(verdict), resolvedAt: east.some(/* @__PURE__ */ new Date()) });
62093
+ removeFromOwningView(decisions, caseId);
62094
+ writeSelectionAt(selectionKey, east.none);
62095
+ return null;
62096
+ }),
62097
+ internal$1.DecisionBindPrimitives.commitState.implement((decisions, judgements, caseId) => {
62098
+ const cid = caseId;
62099
+ const decision = hostQueue(decisions).find((d2) => d2.id === cid);
62100
+ const prompts = (decision == null ? void 0 : decision.prompts) ?? [];
62101
+ const answers = judgementForAt(judgements, cid).answers;
62102
+ const responses = prompts.map((p2) => {
62103
+ var _a2;
62104
+ return (_a2 = answers.get(p2.id)) == null ? void 0 : _a2.type;
62105
+ });
62106
+ if (responses.some((r2) => r2 === "no")) return east.variant("blocked", null);
62107
+ if (responses.some((r2) => r2 === "unknown")) return east.variant("handoff", null);
62108
+ const unanswered = responses.filter((r2) => r2 === void 0).length;
62109
+ if (unanswered > 0) return east.variant("gated", BigInt(unanswered));
62110
+ return east.variant("ready", null);
62111
+ })
61750
62112
  ];
61751
- eastUiComponents.registerPlatformImplementation(DecisionBindPlatform);
62113
+ platform.registerPlatformImplementation(DecisionBindPlatform);
61752
62114
  function useHandleVersion(handle) {
61753
62115
  const staged = getStagedStore();
61754
62116
  const cache3 = getReactiveDatasetCache();
61755
- const state = eastUiComponents.StateRuntime.getStore();
62117
+ const state = platform.StateRuntime.getStore();
61756
62118
  const workspace = cache3.getConfig().workspace ?? "";
61757
62119
  const keys = React.useMemo(() => {
61758
62120
  if (!handle) return [];
@@ -61784,7 +62146,7 @@ function useDecisionHandle(ref) {
61784
62146
  () => ref ? buildDecisionHandle(
61785
62147
  [...ref.decisions],
61786
62148
  ref.judgements,
61787
- eastUiComponents.getSomeorUndefined(ref.slice)
62149
+ platform.getSomeorUndefined(ref.slice)
61788
62150
  ) : null,
61789
62151
  [ref]
61790
62152
  );
@@ -62134,6 +62496,9 @@ const OptionsFacet = React.memo(function OptionsFacet2({ decision, narrow }) {
62134
62496
  const options2 = rankOptions(decision);
62135
62497
  const maxUp = Math.max(...options2.map((o2) => Math.max(o2.value, 0)), 1e-9);
62136
62498
  const maxDown = Math.max(...options2.map((o2) => Math.abs(o2.downside ?? 0)), 1e-9);
62499
+ const valueAxis = eastUiComponents.getSomeorUndefined(decision.valueAxis);
62500
+ const upLabel = (valueAxis == null ? void 0 : valueAxis.label) ?? "Uplift";
62501
+ const signed2 = (valueAxis == null ? void 0 : valueAxis.signed) ?? true;
62137
62502
  if (narrow) {
62138
62503
  const meter = (label, frac, display, tone) => /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { display: "grid", gridTemplateColumns: "80px 1fr 64px", alignItems: "center", gap: "8px", children: [
62139
62504
  /* @__PURE__ */ jsxRuntime.jsx(react.Text, { ...caption, whiteSpace: "nowrap", children: label }),
@@ -62152,7 +62517,7 @@ const OptionsFacet = React.memo(function OptionsFacet2({ decision, narrow }) {
62152
62517
  " ",
62153
62518
  /* @__PURE__ */ jsxRuntime.jsx(react.Text, { as: "span", fontWeight: o2.recommended ? "semibold" : "normal", children: o2.label })
62154
62519
  ] }),
62155
- meter("Uplift", o2.value / maxUp, fmt(decision, o2.value, true), "success"),
62520
+ meter(upLabel, o2.value / maxUp, fmt(decision, o2.value, signed2), signed2 ? "success" : "neutral"),
62156
62521
  meter("If wrong", (o2.downside ?? 0) / maxDown, o2.downside !== void 0 ? fmt(decision, o2.downside, true) : "—", "danger")
62157
62522
  ] }, o2.rank))
62158
62523
  ] });
@@ -62165,7 +62530,7 @@ const OptionsFacet = React.memo(function OptionsFacet2({ decision, narrow }) {
62165
62530
  " evaluated"
62166
62531
  ] }),
62167
62532
  /* @__PURE__ */ jsxRuntime.jsx(react.Text, { ...caption, textAlign: "center", children: "If wrong" }),
62168
- /* @__PURE__ */ jsxRuntime.jsx(react.Text, { ...caption, textAlign: "right", children: "Uplift" })
62533
+ /* @__PURE__ */ jsxRuntime.jsx(react.Text, { ...caption, textAlign: "right", children: upLabel })
62169
62534
  ] }),
62170
62535
  options2.map((o2) => {
62171
62536
  const downFrac = Math.min(Math.abs(o2.downside ?? 0) / maxDown, 1);
@@ -62190,8 +62555,8 @@ const OptionsFacet = React.memo(function OptionsFacet2({ decision, narrow }) {
62190
62555
  /* @__PURE__ */ jsxRuntime.jsx(react.Box, { height: "12px", width: `${Math.round(downFrac * 100)}%`, bg: "fg.danger", opacity: 0.55 })
62191
62556
  ] }) }),
62192
62557
  /* @__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: [
62193
- /* @__PURE__ */ jsxRuntime.jsx(react.Box, { height: "12px", width: `${Math.round(upFrac * 100)}%`, bg: "fg.success", opacity: 0.6 }),
62194
- /* @__PURE__ */ jsxRuntime.jsx(react.Text, { fontSize: "10.5px", fontFamily: "mono", color: "fg.success", flexShrink: 0, children: fmt(decision, o2.value, true) })
62558
+ /* @__PURE__ */ jsxRuntime.jsx(react.Box, { height: "12px", width: `${Math.round(upFrac * 100)}%`, bg: signed2 ? "fg.success" : "fg.subtle", opacity: 0.6 }),
62559
+ /* @__PURE__ */ jsxRuntime.jsx(react.Text, { fontSize: "10.5px", fontFamily: "mono", color: signed2 ? "fg.success" : "fg.muted", flexShrink: 0, children: fmt(decision, o2.value, signed2) })
62195
62560
  ] }) })
62196
62561
  ]
62197
62562
  },
@@ -62376,7 +62741,8 @@ function useLeverPayloads(ref) {
62376
62741
  return (constraint == null ? void 0 : constraint.type) === "Variant" ? constraint.cases ?? {} : {};
62377
62742
  }, [ref, workspace]);
62378
62743
  }
62379
- const Row = React.memo(function Row2({ decision, handle, selected: selected2, narrow, leverPayloads, modify, detail, defaultFacet, apply: apply2, reject: reject2, leaving, storageKey }) {
62744
+ const Row = React.memo(function Row2({ decision, handle, selected: selected2, narrow, leverPayloads, modify, evidence, defaultFacet, facetInclude, apply: apply2, reject: reject2, leaving, storageKey }) {
62745
+ var _a2, _b2;
62380
62746
  const dq = react.useSlotRecipe({ key: "decisionQueue" });
62381
62747
  const status = react.useSlotRecipe({ key: "status" });
62382
62748
  const tabs = react.useSlotRecipe({ key: "facetTabs" });
@@ -62384,10 +62750,15 @@ const Row = React.memo(function Row2({ decision, handle, selected: selected2, na
62384
62750
  const rs = dq({});
62385
62751
  const ts = tabs({});
62386
62752
  const st = status({ status: URGENCY_TONE[decision.urgency.type], size: "md" });
62387
- const [facet, setFacet] = React.useState(defaultFacet);
62753
+ const visibleFacets = React.useMemo(
62754
+ () => FACETS.filter((f2) => f2.key === "modify" ? modify !== void 0 : facetInclude === null || facetInclude.has(f2.key)),
62755
+ [modify, facetInclude]
62756
+ );
62757
+ const effectiveDefault = visibleFacets.some((f2) => f2.key === defaultFacet) ? defaultFacet : ((_a2 = visibleFacets[0]) == null ? void 0 : _a2.key) ?? defaultFacet;
62758
+ const [facet, setFacet] = React.useState(effectiveDefault);
62388
62759
  React.useEffect(() => {
62389
- if (!selected2) setFacet(defaultFacet);
62390
- }, [selected2, defaultFacet]);
62760
+ if (!selected2) setFacet(effectiveDefault);
62761
+ }, [selected2, effectiveDefault]);
62391
62762
  const gate = handle.commitStateFor(decision.id);
62392
62763
  const applyEnabled = gate === null || gate.type === "ready";
62393
62764
  const gatePulse = !applyEnabled && decision.prompts.length > 0;
@@ -62406,10 +62777,10 @@ const Row = React.memo(function Row2({ decision, handle, selected: selected2, na
62406
62777
  return modify(decision, handle.update);
62407
62778
  }, [selected2, facet, modify, decision, handle.update]);
62408
62779
  const canvas = React.useMemo(() => {
62409
- if (!selected2 || facet !== "evidence" || !detail) return null;
62410
- return detail(decision);
62411
- }, [selected2, facet, detail, decision]);
62412
- 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(
62780
+ if (!selected2 || facet !== "evidence" || !evidence) return null;
62781
+ return evidence(decision);
62782
+ }, [selected2, facet, evidence, decision]);
62783
+ const facetTabs = /* @__PURE__ */ jsxRuntime.jsx(react.Box, { css: ts.root, ...narrow ? { display: "flex", width: "100%" } : {}, children: visibleFacets.map((f2) => /* @__PURE__ */ jsxRuntime.jsx(
62413
62784
  react.Box,
62414
62785
  {
62415
62786
  as: "button",
@@ -62455,7 +62826,8 @@ const Row = React.memo(function Row2({ decision, handle, selected: selected2, na
62455
62826
  deadlineSuffix(decision)
62456
62827
  ] })
62457
62828
  ] });
62458
- 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) });
62829
+ const valueSigned = ((_b2 = eastUiComponents.getSomeorUndefined(decision.valueAxis)) == null ? void 0 : _b2.signed) ?? true;
62830
+ 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) });
62459
62831
  return /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { css: rs.rowShell, ...leaving ? { "data-leaving": leaving } : {}, children: [
62460
62832
  narrow ? /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { px: "14px", py: "10px", children: [
62461
62833
  /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { display: "flex", justifyContent: "space-between", alignItems: "baseline", children: [
@@ -62477,7 +62849,7 @@ const Row = React.memo(function Row2({ decision, handle, selected: selected2, na
62477
62849
  ] })
62478
62850
  ] }),
62479
62851
  selected2 && /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { px: narrow ? "14px" : "18px", py: "12px", borderTopWidth: "1px", borderColor: "border.subtle", bg: "bg.canvas", children: [
62480
- facet === "evidence" && /* @__PURE__ */ jsxRuntime.jsx(EvidenceFacet, { decision, children: canvas != null && /* @__PURE__ */ jsxRuntime.jsx(eastUiComponents.EastChakraComponent, { value: canvas, storageKey: `${storageKey}-detail-${decision.id}` }) }),
62852
+ facet === "evidence" && /* @__PURE__ */ jsxRuntime.jsx(EvidenceFacet, { decision, children: canvas != null && /* @__PURE__ */ jsxRuntime.jsx(eastUiComponents.EastChakraComponent, { value: canvas, storageKey: `${storageKey}-evidence-${decision.id}` }) }),
62481
62853
  facet === "options" && /* @__PURE__ */ jsxRuntime.jsx(OptionsFacet, { decision, narrow }),
62482
62854
  facet === "judgement" && /* @__PURE__ */ jsxRuntime.jsx(JudgementFacet, { decision, handle, leverPayloads }),
62483
62855
  facet === "modify" && probe != null && /* @__PURE__ */ jsxRuntime.jsx(eastUiComponents.EastChakraComponent, { value: probe, storageKey: `${storageKey}-modify-${decision.id}` })
@@ -62585,11 +62957,15 @@ const EastChakraDecisionQueue = React.memo(function EastChakraDecisionQueue2({ v
62585
62957
  () => eastUiComponents.getSomeorUndefined(value.modify),
62586
62958
  [value.modify]
62587
62959
  );
62588
- const detail = React.useMemo(
62589
- () => eastUiComponents.getSomeorUndefined(value.detail),
62590
- [value.detail]
62960
+ const evidence = React.useMemo(
62961
+ () => eastUiComponents.getSomeorUndefined(value.evidence),
62962
+ [value.evidence]
62591
62963
  );
62592
62964
  const defaultFacet = ((_a2 = eastUiComponents.getSomeorUndefined(value.defaultFacet)) == null ? void 0 : _a2.type) ?? "evidence";
62965
+ const facetInclude = React.useMemo(() => {
62966
+ const facets = eastUiComponents.getSomeorUndefined(value.facets);
62967
+ return facets === void 0 ? null : new Set(facets.map((f2) => f2.type));
62968
+ }, [value.facets]);
62593
62969
  const defaultExpanded = eastUiComponents.getSomeorUndefined(value.defaultExpanded);
62594
62970
  const selectedId = handle.selected ?? (defaultExpanded == null ? void 0 : defaultExpanded.id) ?? null;
62595
62971
  const resolve2 = React.useCallback((ds, hook2, reason) => {
@@ -62635,9 +63011,9 @@ const EastChakraDecisionQueue = React.memo(function EastChakraDecisionQueue2({ v
62635
63011
  return m2;
62636
63012
  }, [exiting]);
62637
63013
  if (decisions === null) {
62638
- return /* @__PURE__ */ jsxRuntime.jsx(react.Box, { layerStyle: "frame", p: "16px", children: /* @__PURE__ */ jsxRuntime.jsx(react.Text, { color: "fg.muted", fontSize: "13px", children: "Loading decisions…" }) });
63014
+ return /* @__PURE__ */ jsxRuntime.jsx(react.Box, { layerStyle: "surface.frameless", p: "16px", children: /* @__PURE__ */ jsxRuntime.jsx(react.Text, { color: "fg.muted", fontSize: "13px", children: "Loading decisions…" }) });
62639
63015
  }
62640
- return /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { ref: rootRef, layerStyle: "frame", overflow: "hidden", children: [
63016
+ return /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { ref: rootRef, layerStyle: "surface.frameless", overflow: "hidden", children: [
62641
63017
  /* @__PURE__ */ jsxRuntime.jsxs(react.Box, { css: es.root, children: [
62642
63018
  /* @__PURE__ */ jsxRuntime.jsx(react.Box, { css: es.lbl, children: heading }),
62643
63019
  sliceHandle !== null && railAffordances !== void 0 && /* @__PURE__ */ jsxRuntime.jsx(react.Box, { display: "flex", alignItems: "center", minWidth: "0", flex: "1", justifyContent: "flex-end", marginRight: "10px", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -62676,8 +63052,9 @@ const EastChakraDecisionQueue = React.memo(function EastChakraDecisionQueue2({ v
62676
63052
  narrow,
62677
63053
  leverPayloads,
62678
63054
  modify,
62679
- detail,
63055
+ evidence,
62680
63056
  defaultFacet,
63057
+ facetInclude,
62681
63058
  apply: apply2,
62682
63059
  reject: reject2,
62683
63060
  leaving: exitingReasons.get(d2.id),
@@ -62691,7 +63068,7 @@ const EastChakraDecisionQueue = React.memo(function EastChakraDecisionQueue2({ v
62691
63068
  )
62692
63069
  ] });
62693
63070
  });
62694
- eastUiComponents.implementUIComponent(internal.DecisionQueue.Component, EastChakraDecisionQueue);
63071
+ eastUiComponents.implementUIComponent(internal$1.DecisionQueue.Component, EastChakraDecisionQueue);
62695
63072
  function verdictPresentation(verdict) {
62696
63073
  switch (verdict.type) {
62697
63074
  case "accepted":
@@ -62795,7 +63172,7 @@ const EastChakraDecisionJournal = React.memo(function EastChakraDecisionJournal2
62795
63172
  )
62796
63173
  ] });
62797
63174
  });
62798
- eastUiComponents.implementUIComponent(internal.DecisionJournal.Component, EastChakraDecisionJournal);
63175
+ eastUiComponents.implementUIComponent(internal$1.DecisionJournal.Component, EastChakraDecisionJournal);
62799
63176
  function formatApiError(error3) {
62800
63177
  if (error3 instanceof e3ApiClient.ApiError && error3.details != null) {
62801
63178
  const details = error3.details;
@@ -63109,12 +63486,7 @@ function useDatasetValue(apiUrl, repo, workspace, datasetPath, options2) {
63109
63486
  queryKey: ["datasetValue", apiUrl, repo, workspace, datasetPath, hash2 ?? null],
63110
63487
  queryFn: async () => {
63111
63488
  const result = await e3ApiClient.datasetGet(apiUrl, repo, workspace, pathParts, reqOpts);
63112
- const t02 = performance.now();
63113
63489
  const decoded = east.decodeBeast2For(type, { platform: platformImpls })(result.data);
63114
- const kind = (type == null ? void 0 : type.type) ?? "unknown";
63115
- console.log(
63116
- `[east-value] decode ${kind} ${(result.data.length / 1024).toFixed(1)}KB in ${(performance.now() - t02).toFixed(1)}ms (${datasetPath})`
63117
- );
63118
63490
  return { decoded, sizeBytes: result.data.length };
63119
63491
  },
63120
63492
  enabled: enabled && !!workspace && !!datasetPath && hash2 != null,
@@ -63735,7 +64107,7 @@ const UITaskPreview = React.memo(function UITaskPreview2({
63735
64107
  const manifest = React.useMemo(() => {
63736
64108
  if (!details || !isUI) return null;
63737
64109
  const meta3 = getTaskMetadata(details);
63738
- return meta3 ? internal.decodeManifest(meta3) : { paths: [], functions: [], records: [] };
64110
+ return meta3 ? internal$1.decodeManifest(meta3) : { paths: [], functions: [], records: [] };
63739
64111
  }, [details, isUI]);
63740
64112
  const outputPath = details ? treePathToString$1(details.output) : null;
63741
64113
  const preloads = React.useMemo(