@elaraai/e3-ui-components 1.0.79 → 1.0.81
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/README.md +1 -1
- package/dist/components/DatasetPreview.d.ts +10 -2
- package/dist/components/DatasetPreview.d.ts.map +1 -1
- package/dist/components/EastValueViewer.d.ts.map +1 -1
- package/dist/components/PagedDatasetPreview.d.ts +15 -1
- package/dist/components/PagedDatasetPreview.d.ts.map +1 -1
- package/dist/components/TaskPreview.d.ts.map +1 -1
- package/dist/components/UITaskPreview.d.ts +7 -3
- package/dist/components/UITaskPreview.d.ts.map +1 -1
- package/dist/decision/constraint-format.d.ts +15 -7
- package/dist/decision/constraint-format.d.ts.map +1 -1
- package/dist/decision/contract.d.ts +28 -0
- package/dist/decision/contract.d.ts.map +1 -0
- package/dist/decision/facets.d.ts +21 -3
- package/dist/decision/facets.d.ts.map +1 -1
- package/dist/decision/grouping.d.ts +11 -0
- package/dist/decision/grouping.d.ts.map +1 -1
- package/dist/decision/handle-runtime.d.ts.map +1 -1
- package/dist/decision/journal.d.ts.map +1 -1
- package/dist/decision/lever-editor.d.ts +11 -18
- package/dist/decision/lever-editor.d.ts.map +1 -1
- package/dist/decision/queue.d.ts.map +1 -1
- package/dist/diff/format.d.ts +20 -12
- package/dist/diff/format.d.ts.map +1 -1
- package/dist/diff/index.d.ts.map +1 -1
- package/dist/diff/manual.d.ts +37 -18
- package/dist/diff/manual.d.ts.map +1 -1
- package/dist/diff/walker.d.ts +14 -6
- package/dist/diff/walker.d.ts.map +1 -1
- package/dist/experiment/charts.d.ts +4 -1
- package/dist/experiment/charts.d.ts.map +1 -1
- package/dist/experiment/derive.d.ts +25 -5
- package/dist/experiment/derive.d.ts.map +1 -1
- package/dist/experiment/index.d.ts.map +1 -1
- package/dist/experiment/run-runtime.d.ts +4 -8
- package/dist/experiment/run-runtime.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useDatasetValue.d.ts +13 -2
- package/dist/hooks/useDatasetValue.d.ts.map +1 -1
- package/dist/hooks/useTaskDetails.d.ts +1 -5
- package/dist/hooks/useTaskDetails.d.ts.map +1 -1
- package/dist/hooks/workspaces.d.ts +16 -3
- package/dist/hooks/workspaces.d.ts.map +1 -1
- package/dist/index.cjs +1361 -1028
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1385 -1052
- package/dist/index.js.map +1 -1
- package/dist/platform/bind-runtime.d.ts +14 -5
- package/dist/platform/bind-runtime.d.ts.map +1 -1
- package/dist/platform/dataset-hooks.d.ts +12 -4
- package/dist/platform/dataset-hooks.d.ts.map +1 -1
- package/dist/platform/dataset-store.d.ts +47 -11
- package/dist/platform/dataset-store.d.ts.map +1 -1
- package/dist/platform/func-runtime.d.ts +16 -6
- package/dist/platform/func-runtime.d.ts.map +1 -1
- package/dist/platform/index.d.ts +1 -1
- package/dist/platform/index.d.ts.map +1 -1
- package/dist/platform/paged-runtime.d.ts +183 -49
- package/dist/platform/paged-runtime.d.ts.map +1 -1
- package/dist/platform/record-runtime.d.ts +14 -4
- package/dist/platform/record-runtime.d.ts.map +1 -1
- package/dist/platform/staged-store.d.ts +19 -2
- package/dist/platform/staged-store.d.ts.map +1 -1
- package/package.json +16 -15
package/dist/index.js
CHANGED
|
@@ -18,22 +18,22 @@ var __privateWrapper = (obj, member, setter, getter) => ({
|
|
|
18
18
|
}
|
|
19
19
|
});
|
|
20
20
|
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;
|
|
21
|
-
import { variant, SortedMap, compareFor, EastError, fromEastTypeValue, East, none as none$1, some, OptionType, BooleanType, NullType, ConflictError, equalFor, toEastTypeValue, PatchType, diffFor, applyFor, encodeBeast2For, decodeBeast2For, BlobType, IntegerType,
|
|
22
|
-
import { EastTypeType } from "@elaraai/east/internal";
|
|
23
|
-
import { DataBindModeType, DataBindPrimitives, bindPlatformFn, DataPagedPrimitives, bindPagedPlatformFn, FuncBindPrimitives, FuncErrorType, FuncStatusType, funcBindPlatformFn, RecordBindPrimitives, recordBindPlatformFn, Diff, Ontology, FuncBindHandleType, Experiment, decisionBindPlatformFn, DecisionBindPrimitives, DecisionConstraintType, DiffBindingType, CommitStateType, VerdictType, AnswerType, judgementInputType, DecisionType, DecisionQueue, DecisionJournal
|
|
21
|
+
import { variant, SortedMap, compareFor, EastError, fromEastTypeValue, East, none as none$1, some, OptionType, BooleanType, NullType, ConflictError, equalFor, toEastTypeValue, PatchType, diffFor, applyFor, encodeBeast2For, decodeBeast2For, BlobType, StringType, IntegerType, isTypeValueEqual, StructType, walkPatch, pathToString, pathDisplay, parseFor, printFor, FloatType, equivalentFor, prunePatchFor, detectConflictsFor, mergeWithResolutionsFor, validatePatchFor, canonicalTypeValue, ArrayType, EastTypeValueType, defaultValue, DateTimeType } from "@elaraai/east";
|
|
22
|
+
import { EastTypeType, formatDateTime, parseDateTimeFormatted, tokenizeDateTimeFormat } from "@elaraai/east/internal";
|
|
23
|
+
import { DataBindModeType, DataBindPrimitives, bindPlatformFn, DataPagedPrimitives, bindPagedPlatformFn, bindPagedPinnedPlatformFn, FuncBindPrimitives, FuncErrorType, FuncStatusType, funcBindPlatformFn, RecordBindPrimitives, recordBindPlatformFn, Diff, Ontology, FuncBindHandleType, Experiment, decisionBindPlatformFn, DecisionBindPrimitives, DecisionConstraintType, DiffBindingType, CommitStateType, VerdictType, AnswerType, judgementInputType, DecisionType, DecisionQueue, DecisionJournal } from "@elaraai/e3-ui/internal";
|
|
24
24
|
import { registerReactiveTracker, registerPlatformImplementation, StateRuntime, getRegisteredPlatformImplementations, boundSliceConfig } from "@elaraai/east-ui-components/platform";
|
|
25
|
-
import { TreePathType, DatasetStatusType } from "@elaraai/e3-types";
|
|
26
|
-
import { workspaceStatus, datasetListAt, datasetList, dataflowExecuteLaunch, datasetSet, datasetGet, ApiError, datasetFindKey, datasetGetPage, workspaceFunctionCall, workspaceFunctionList, workspaceRecordHistory, workspaceRecordMutate, workspaceRecordDescribe, repoCreate, repoGc, repoGcStart, repoGcStatus, repoList, repoRemove, repoStatus, packageExport, packageGet, packageImport, packageList, packageRemove, workspaceCreate, workspaceDeploy, workspaceExport, workspaceGet, workspaceList, workspaceRemove,
|
|
27
|
-
import { SeekQueryType, SeekRangeType, ValueTree } from "@elaraai/east-ui";
|
|
25
|
+
import { TreePathType, DatasetStatusType, pathToString as pathToString$1 } from "@elaraai/e3-types";
|
|
26
|
+
import { workspaceStatus, datasetListAt, datasetList, dataflowExecuteLaunch, datasetSet, datasetGet, ApiError, DatasetHashMismatchError, datasetGetStatus, datasetFindKey, datasetGetPage, workspaceFunctionCall, workspaceFunctionList, workspaceRecordHistory, workspaceRecordMutate, workspaceRecordDescribe, repoCreate, repoGc, repoGcStart, repoGcStatus, repoList, repoRemove, repoStatus, packageExport, packageGet, packageImport, packageList, packageRemove, workspaceCreate, workspaceDeploy, workspaceExport, workspaceGet, workspaceList, workspaceRemove, datasetListRecursive, datasetListRecursivePaths, datasetListWithStatus, taskExecutionList, taskGet, taskList, dataflowCancel, dataflowExecute, dataflowExecutePoll, dataflowGraph, taskLogs } from "@elaraai/e3-api-client";
|
|
27
|
+
import { SeekQueryType, SeekRangeType, slicePredicateMatches, ValueTree } from "@elaraai/east-ui";
|
|
28
28
|
import { jsx as jsx$1, Fragment, jsxs } from "react/jsx-runtime";
|
|
29
29
|
import * as React from "react";
|
|
30
|
-
import React__default, { useId, useMemo, useContext, createContext, useRef,
|
|
30
|
+
import React__default, { useId, useMemo, useContext, createContext, useRef, useState, useEffect, useCallback, useSyncExternalStore, memo, forwardRef, useLayoutEffect, Fragment as Fragment$1, Component } from "react";
|
|
31
31
|
import { Box, Flex, Text, HStack, Input, useSlotRecipe, useRecipe, VStack, useToken, Drawer, Portal, Field, NativeSelect, Textarea, chakra, Tooltip, SegmentGroup, Menu, HoverCard, useChakraContext, Spinner, Code, Clipboard, IconButton, Button, Tabs, Badge, useTabs } from "@chakra-ui/react";
|
|
32
|
-
import { implementUIComponent, getSomeorUndefined, formatPredicate, SliceEditPopover, SlicePredicateBuilder, EastChakraSelect, EastChakraStringInput, EastChakraDateTimeInput, EastChakraFloatInput, EastChakraIntegerInput,
|
|
32
|
+
import { formatters, useFormatters, useDataStable, implementUIComponent, getSomeorUndefined, formatPredicate, SliceEditPopover, SlicePredicateBuilder, EastChakraSelect, EastChakraStringInput, EastChakraDateTimeInput, EastChakraFloatInput, EastChakraIntegerInput, useSliceReactivity, useContainerBelow, usePersistedState, SliceRailCluster, EastChakraComponent, ClauseChip, StateImpl, NavImpl, SliceImpl, SliceApplyImpl, OverlayImpl, ClipboardImpl, DownloadImpl, ShareImpl, LoadingIcon, DatasetKeySearch, EastChakraValueTree, keyRangePredicates, createUIStore, UIStoreProvider } from "@elaraai/east-ui-components";
|
|
33
33
|
import { DatasetKeySearch as DatasetKeySearch2 } from "@elaraai/east-ui-components";
|
|
34
34
|
import { createPortal } from "react-dom";
|
|
35
35
|
import { sliceMatches, pruneRetainedPages } from "@elaraai/east-ui/internal";
|
|
36
|
-
import { QueryClient as QueryClient$1, QueryClientProvider, useMutation, useQuery,
|
|
36
|
+
import { QueryClient as QueryClient$1, QueryClientProvider, useMutation, useQuery, useQueryClient, keepPreviousData } from "@tanstack/react-query";
|
|
37
37
|
import { useVirtualizer } from "@tanstack/react-virtual";
|
|
38
38
|
var Subscribable = class {
|
|
39
39
|
constructor() {
|
|
@@ -2060,6 +2060,7 @@ const realClock = {
|
|
|
2060
2060
|
return { clear: () => clearInterval(id3) };
|
|
2061
2061
|
}
|
|
2062
2062
|
};
|
|
2063
|
+
const HASH_POLL_MS = 1e3;
|
|
2063
2064
|
function createDefaultDatasetApi(apiUrl, repo, getToken) {
|
|
2064
2065
|
const opts = () => ({ token: getToken() });
|
|
2065
2066
|
return {
|
|
@@ -2125,12 +2126,17 @@ class ReactiveDatasetCache {
|
|
|
2125
2126
|
__publicField(this, "keyVersions", /* @__PURE__ */ new Map());
|
|
2126
2127
|
// Workspace status polling — groups subscriptions by workspace for
|
|
2127
2128
|
// efficiency. Each entry holds the active interval handle from the
|
|
2128
|
-
// injected {@link Clock} so tests can drive ticking deterministically
|
|
2129
|
+
// injected {@link Clock} so tests can drive ticking deterministically,
|
|
2130
|
+
// and each polled path with how many watchers poll it.
|
|
2129
2131
|
__publicField(this, "workspacePollers", /* @__PURE__ */ new Map());
|
|
2130
2132
|
__publicField(this, "clock");
|
|
2131
2133
|
// In-flight poll dedup — concurrent callers (interval tick + a
|
|
2132
2134
|
// post-write trigger) share a single round-trip rather than racing.
|
|
2133
2135
|
__publicField(this, "inFlightPolls", /* @__PURE__ */ new Map());
|
|
2136
|
+
// Hash-only watches, by workspace and path: each callback with the hash it
|
|
2137
|
+
// was last told. A watched path rides its workspace's poll, but its
|
|
2138
|
+
// content is never fetched — a paged source reads windows, never the value.
|
|
2139
|
+
__publicField(this, "hashWatches", /* @__PURE__ */ new Map());
|
|
2134
2140
|
// Batching
|
|
2135
2141
|
__publicField(this, "batchDepth", 0);
|
|
2136
2142
|
__publicField(this, "changedKeys", /* @__PURE__ */ new Set());
|
|
@@ -2219,9 +2225,7 @@ class ReactiveDatasetCache {
|
|
|
2219
2225
|
hash: void 0,
|
|
2220
2226
|
status: variant("stale", null)
|
|
2221
2227
|
});
|
|
2222
|
-
|
|
2223
|
-
void this.pollWorkspaceStatus(workspace);
|
|
2224
|
-
}
|
|
2228
|
+
void this.refresh(workspace);
|
|
2225
2229
|
} catch (error3) {
|
|
2226
2230
|
if (!this.destroyed && this.writeEpochs.get(key) === myEpoch) {
|
|
2227
2231
|
const baseline = this.writeBaselines.get(key);
|
|
@@ -2327,15 +2331,15 @@ class ReactiveDatasetCache {
|
|
|
2327
2331
|
* 3. Only fetches full content when hash changes
|
|
2328
2332
|
*
|
|
2329
2333
|
* Multiple subscriptions to the same workspace share a single poller.
|
|
2330
|
-
* Pair with {@link clearRefetchInterval} on unmount so the
|
|
2331
|
-
* stop when nothing is watching.
|
|
2334
|
+
* Pair each call with one {@link clearRefetchInterval} on unmount so the
|
|
2335
|
+
* poller can stop when nothing is watching.
|
|
2332
2336
|
*/
|
|
2333
2337
|
setRefetchInterval(workspace, path2, intervalMs) {
|
|
2334
2338
|
var _a2;
|
|
2335
2339
|
const pathStr = datasetPathToString(path2);
|
|
2336
2340
|
let poller = this.workspacePollers.get(workspace);
|
|
2337
2341
|
if (poller) {
|
|
2338
|
-
poller.paths.
|
|
2342
|
+
poller.paths.set(pathStr, (poller.paths.get(pathStr) ?? 0) + 1);
|
|
2339
2343
|
if (intervalMs < poller.intervalMs) {
|
|
2340
2344
|
(_a2 = poller.handle) == null ? void 0 : _a2.clear();
|
|
2341
2345
|
poller.intervalMs = intervalMs;
|
|
@@ -2347,7 +2351,7 @@ class ReactiveDatasetCache {
|
|
|
2347
2351
|
} else {
|
|
2348
2352
|
poller = {
|
|
2349
2353
|
intervalMs,
|
|
2350
|
-
paths: /* @__PURE__ */ new
|
|
2354
|
+
paths: /* @__PURE__ */ new Map([[pathStr, 1]]),
|
|
2351
2355
|
handle: this.clock.setInterval(
|
|
2352
2356
|
() => this.pollWorkspaceStatus(workspace),
|
|
2353
2357
|
intervalMs
|
|
@@ -2358,23 +2362,79 @@ class ReactiveDatasetCache {
|
|
|
2358
2362
|
}
|
|
2359
2363
|
}
|
|
2360
2364
|
/**
|
|
2361
|
-
* Stop polling a dataset
|
|
2362
|
-
*
|
|
2365
|
+
* Stop polling a dataset for one watcher; the path goes when its last
|
|
2366
|
+
* watcher clears it, and the workspace poller is torn down when its last
|
|
2367
|
+
* path goes.
|
|
2363
2368
|
*/
|
|
2364
2369
|
clearRefetchInterval(workspace, path2) {
|
|
2365
|
-
var _a2;
|
|
2366
2370
|
const poller = this.workspacePollers.get(workspace);
|
|
2367
2371
|
if (!poller) return;
|
|
2368
|
-
|
|
2369
|
-
|
|
2372
|
+
const pathStr = datasetPathToString(path2);
|
|
2373
|
+
const watchers = (poller.paths.get(pathStr) ?? 0) - 1;
|
|
2374
|
+
if (watchers > 0) {
|
|
2375
|
+
poller.paths.set(pathStr, watchers);
|
|
2376
|
+
return;
|
|
2377
|
+
}
|
|
2378
|
+
poller.paths.delete(pathStr);
|
|
2379
|
+
this.stopIdlePoller(workspace);
|
|
2380
|
+
}
|
|
2381
|
+
/**
|
|
2382
|
+
* Follow a dataset's content hash without fetching its content; see the
|
|
2383
|
+
* interface doc.
|
|
2384
|
+
*/
|
|
2385
|
+
watchHash(workspace, path2, onHash, intervalMs = HASH_POLL_MS) {
|
|
2386
|
+
var _a2;
|
|
2387
|
+
const pathStr = datasetPathToString(path2);
|
|
2388
|
+
let byPath = this.hashWatches.get(workspace);
|
|
2389
|
+
if (!byPath) {
|
|
2390
|
+
byPath = /* @__PURE__ */ new Map();
|
|
2391
|
+
this.hashWatches.set(workspace, byPath);
|
|
2392
|
+
}
|
|
2393
|
+
let callbacks = byPath.get(pathStr);
|
|
2394
|
+
if (!callbacks) {
|
|
2395
|
+
callbacks = /* @__PURE__ */ new Map();
|
|
2396
|
+
byPath.set(pathStr, callbacks);
|
|
2397
|
+
}
|
|
2398
|
+
callbacks.set(onHash, void 0);
|
|
2399
|
+
const poller = this.workspacePollers.get(workspace);
|
|
2400
|
+
if (!poller) {
|
|
2401
|
+
this.workspacePollers.set(workspace, {
|
|
2402
|
+
intervalMs,
|
|
2403
|
+
paths: /* @__PURE__ */ new Map(),
|
|
2404
|
+
handle: this.clock.setInterval(() => this.pollWorkspaceStatus(workspace), intervalMs)
|
|
2405
|
+
});
|
|
2406
|
+
void this.pollWorkspaceStatus(workspace);
|
|
2407
|
+
} else if (intervalMs < poller.intervalMs) {
|
|
2370
2408
|
(_a2 = poller.handle) == null ? void 0 : _a2.clear();
|
|
2371
|
-
|
|
2409
|
+
poller.intervalMs = intervalMs;
|
|
2410
|
+
poller.handle = this.clock.setInterval(() => this.pollWorkspaceStatus(workspace), intervalMs);
|
|
2372
2411
|
}
|
|
2412
|
+
return () => {
|
|
2413
|
+
const watched = this.hashWatches.get(workspace);
|
|
2414
|
+
const set3 = watched == null ? void 0 : watched.get(pathStr);
|
|
2415
|
+
if (!watched || !set3) return;
|
|
2416
|
+
set3.delete(onHash);
|
|
2417
|
+
if (set3.size === 0) watched.delete(pathStr);
|
|
2418
|
+
if (watched.size === 0) this.hashWatches.delete(workspace);
|
|
2419
|
+
this.stopIdlePoller(workspace);
|
|
2420
|
+
};
|
|
2421
|
+
}
|
|
2422
|
+
/** Stops a workspace's poller once it has no path to reconcile and no hash
|
|
2423
|
+
* to follow — without this, a long-lived session polls forever. */
|
|
2424
|
+
stopIdlePoller(workspace) {
|
|
2425
|
+
var _a2;
|
|
2426
|
+
const poller = this.workspacePollers.get(workspace);
|
|
2427
|
+
if (!poller || poller.paths.size > 0 || this.hashWatches.has(workspace)) return;
|
|
2428
|
+
(_a2 = poller.handle) == null ? void 0 : _a2.clear();
|
|
2429
|
+
this.workspacePollers.delete(workspace);
|
|
2373
2430
|
}
|
|
2374
2431
|
refresh(workspace) {
|
|
2375
2432
|
if (this.destroyed) return Promise.resolve();
|
|
2376
2433
|
if (!this.workspacePollers.has(workspace)) return Promise.resolve();
|
|
2377
|
-
|
|
2434
|
+
const inFlight = this.inFlightPolls.get(workspace);
|
|
2435
|
+
if (inFlight === void 0) return this.pollWorkspaceStatus(workspace);
|
|
2436
|
+
const again = () => this.destroyed || !this.workspacePollers.has(workspace) ? void 0 : this.pollWorkspaceStatus(workspace);
|
|
2437
|
+
return inFlight.then(again, again);
|
|
2378
2438
|
}
|
|
2379
2439
|
/**
|
|
2380
2440
|
* Poll workspace status and reconcile the cache with the server.
|
|
@@ -2390,11 +2450,12 @@ class ReactiveDatasetCache {
|
|
|
2390
2450
|
return promise4;
|
|
2391
2451
|
}
|
|
2392
2452
|
async doPollWorkspaceStatus(workspace) {
|
|
2453
|
+
var _a2;
|
|
2393
2454
|
if (this.destroyed) return;
|
|
2394
2455
|
const poller = this.workspacePollers.get(workspace);
|
|
2395
|
-
if (!poller || poller.paths.size === 0) return;
|
|
2456
|
+
if (!poller || poller.paths.size === 0 && !this.hashWatches.has(workspace)) return;
|
|
2396
2457
|
const epochsAtStart = /* @__PURE__ */ new Map();
|
|
2397
|
-
for (const pathStr of poller.paths) {
|
|
2458
|
+
for (const pathStr of poller.paths.keys()) {
|
|
2398
2459
|
const key = pathStr ? `${workspace}.${pathStr}` : workspace;
|
|
2399
2460
|
epochsAtStart.set(key, this.writeEpochs.get(key) ?? 0);
|
|
2400
2461
|
}
|
|
@@ -2408,15 +2469,28 @@ class ReactiveDatasetCache {
|
|
|
2408
2469
|
if (this.destroyed) return;
|
|
2409
2470
|
const infoByPath = /* @__PURE__ */ new Map();
|
|
2410
2471
|
for (const info of status.datasets) infoByPath.set(info.path, info);
|
|
2472
|
+
for (const [pathStr, callbacks] of this.hashWatches.get(workspace) ?? []) {
|
|
2473
|
+
const info = infoByPath.get(pathStr ? `.${pathStr}` : "");
|
|
2474
|
+
const hash2 = ((_a2 = info == null ? void 0 : info.hash) == null ? void 0 : _a2.type) === "some" ? info.hash.value : null;
|
|
2475
|
+
for (const [onHash, told] of [...callbacks]) {
|
|
2476
|
+
if (told === hash2 || !callbacks.has(onHash)) continue;
|
|
2477
|
+
callbacks.set(onHash, hash2);
|
|
2478
|
+
try {
|
|
2479
|
+
onHash(hash2);
|
|
2480
|
+
} catch (error3) {
|
|
2481
|
+
console.error(`A hash watch on ${workspace}.${pathStr} failed:`, error3);
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2411
2485
|
const pending = [];
|
|
2412
2486
|
this.batch(() => {
|
|
2413
|
-
var
|
|
2414
|
-
for (const pathStr of poller.paths) {
|
|
2487
|
+
var _a3;
|
|
2488
|
+
for (const pathStr of poller.paths.keys()) {
|
|
2415
2489
|
const e3Path = pathStr ? `.${pathStr}` : "";
|
|
2416
2490
|
const info = infoByPath.get(e3Path);
|
|
2417
2491
|
const key = pathStr ? `${workspace}.${pathStr}` : workspace;
|
|
2418
2492
|
const path2 = this.stringToPath(pathStr);
|
|
2419
|
-
const currentHash = ((
|
|
2493
|
+
const currentHash = ((_a3 = info == null ? void 0 : info.hash) == null ? void 0 : _a3.type) === "some" ? info.hash.value : null;
|
|
2420
2494
|
const knownHash = this.knownHashes.get(key);
|
|
2421
2495
|
if (info == null ? void 0 : info.status) {
|
|
2422
2496
|
const previous = this.statuses.get(key);
|
|
@@ -2582,6 +2656,7 @@ class ReactiveDatasetCache {
|
|
|
2582
2656
|
}
|
|
2583
2657
|
this.workspacePollers.clear();
|
|
2584
2658
|
this.inFlightPolls.clear();
|
|
2659
|
+
this.hashWatches.clear();
|
|
2585
2660
|
this.keySubscribers.clear();
|
|
2586
2661
|
this.globalSubscribers.clear();
|
|
2587
2662
|
this.knownHashes.clear();
|
|
@@ -2696,9 +2771,16 @@ class MemoryStagedAdapter {
|
|
|
2696
2771
|
this.map.clear();
|
|
2697
2772
|
}
|
|
2698
2773
|
}
|
|
2774
|
+
const SCOPE_SEPARATOR = "\0";
|
|
2775
|
+
function cacheKeyOf(key) {
|
|
2776
|
+
return key.slice(key.indexOf(SCOPE_SEPARATOR) + 1);
|
|
2777
|
+
}
|
|
2699
2778
|
class StagedStore {
|
|
2700
2779
|
constructor(adapter) {
|
|
2780
|
+
// By scope and `datasetCacheKey`; subscribers and versions go by the
|
|
2781
|
+
// `datasetCacheKey` alone, which is what a reactive view tracks.
|
|
2701
2782
|
__publicField(this, "entries", /* @__PURE__ */ new Map());
|
|
2783
|
+
__publicField(this, "scope", null);
|
|
2702
2784
|
__publicField(this, "subscribers", /* @__PURE__ */ new Map());
|
|
2703
2785
|
__publicField(this, "versions", /* @__PURE__ */ new Map());
|
|
2704
2786
|
__publicField(this, "adapter");
|
|
@@ -2722,25 +2804,25 @@ class StagedStore {
|
|
|
2722
2804
|
}
|
|
2723
2805
|
}
|
|
2724
2806
|
hasPending(workspace, path2) {
|
|
2725
|
-
return this.entries.has(
|
|
2807
|
+
return this.entries.has(this.keyOf(workspace, path2));
|
|
2726
2808
|
}
|
|
2727
2809
|
getBuffered(workspace, path2) {
|
|
2728
2810
|
var _a2;
|
|
2729
|
-
return (_a2 = this.entries.get(
|
|
2811
|
+
return (_a2 = this.entries.get(this.keyOf(workspace, path2))) == null ? void 0 : _a2.buffered;
|
|
2730
2812
|
}
|
|
2731
2813
|
getSnapshot(workspace, path2) {
|
|
2732
2814
|
var _a2;
|
|
2733
|
-
return (_a2 = this.entries.get(
|
|
2815
|
+
return (_a2 = this.entries.get(this.keyOf(workspace, path2))) == null ? void 0 : _a2.snapshot;
|
|
2734
2816
|
}
|
|
2735
2817
|
getEntry(workspace, path2) {
|
|
2736
|
-
return this.entries.get(
|
|
2818
|
+
return this.entries.get(this.keyOf(workspace, path2));
|
|
2737
2819
|
}
|
|
2738
2820
|
write(workspace, path2, snapshotIfNew, buffered) {
|
|
2739
|
-
const key =
|
|
2821
|
+
const key = this.keyOf(workspace, path2);
|
|
2740
2822
|
const existing = this.entries.get(key);
|
|
2741
2823
|
const next2 = existing ? { snapshot: existing.snapshot, buffered } : { snapshot: snapshotIfNew, buffered };
|
|
2742
2824
|
this.entries.set(key, next2);
|
|
2743
|
-
this.notify(
|
|
2825
|
+
this.notify(datasetCacheKey(workspace, path2));
|
|
2744
2826
|
const persisted = {
|
|
2745
2827
|
snapshot: next2.snapshot,
|
|
2746
2828
|
buffered: next2.buffered
|
|
@@ -2748,15 +2830,26 @@ class StagedStore {
|
|
|
2748
2830
|
this.persist(key, () => this.adapter.save(key, persisted));
|
|
2749
2831
|
}
|
|
2750
2832
|
discard(workspace, path2) {
|
|
2751
|
-
const key =
|
|
2833
|
+
const key = this.keyOf(workspace, path2);
|
|
2752
2834
|
if (!this.entries.has(key)) return false;
|
|
2753
2835
|
this.entries.delete(key);
|
|
2754
|
-
this.notify(
|
|
2836
|
+
this.notify(datasetCacheKey(workspace, path2));
|
|
2755
2837
|
this.persist(key, () => this.adapter.remove(key));
|
|
2756
2838
|
return true;
|
|
2757
2839
|
}
|
|
2758
2840
|
listKeys() {
|
|
2759
|
-
|
|
2841
|
+
const prefix2 = `${this.scope ?? ""}${SCOPE_SEPARATOR}`;
|
|
2842
|
+
return [...this.entries.keys()].filter((key) => key.startsWith(prefix2)).map(cacheKeyOf);
|
|
2843
|
+
}
|
|
2844
|
+
setScope(scope) {
|
|
2845
|
+
const before = this.scope;
|
|
2846
|
+
this.scope = scope;
|
|
2847
|
+
this.notifyScopes(before, scope);
|
|
2848
|
+
return () => {
|
|
2849
|
+
if (this.scope !== scope) return;
|
|
2850
|
+
this.scope = null;
|
|
2851
|
+
this.notifyScopes(scope, null);
|
|
2852
|
+
};
|
|
2760
2853
|
}
|
|
2761
2854
|
subscribe(key, callback) {
|
|
2762
2855
|
let set3 = this.subscribers.get(key);
|
|
@@ -2779,15 +2872,29 @@ class StagedStore {
|
|
|
2779
2872
|
this.errorListeners.delete(cb);
|
|
2780
2873
|
};
|
|
2781
2874
|
}
|
|
2782
|
-
/** Test-only: clear in-memory + persisted state. */
|
|
2875
|
+
/** Test-only: clear in-memory + persisted state, in every scope. */
|
|
2783
2876
|
async clear() {
|
|
2784
2877
|
const keys = [...this.entries.keys()];
|
|
2785
2878
|
this.entries.clear();
|
|
2786
|
-
for (const key of keys) this.notify(key);
|
|
2879
|
+
for (const key of new Set(keys.map(cacheKeyOf))) this.notify(key);
|
|
2787
2880
|
await this.flushPending();
|
|
2788
2881
|
await this.adapter.clear();
|
|
2789
2882
|
}
|
|
2790
2883
|
// ----- internals -------------------------------------------------------
|
|
2884
|
+
/** The key a path's entry is held under in the current scope. */
|
|
2885
|
+
keyOf(workspace, path2) {
|
|
2886
|
+
return `${this.scope ?? ""}${SCOPE_SEPARATOR}${datasetCacheKey(workspace, path2)}`;
|
|
2887
|
+
}
|
|
2888
|
+
/** Tells every path with an entry in either scope that what it reads has
|
|
2889
|
+
* changed: the scope's move shows one's entries and hides the other's. */
|
|
2890
|
+
notifyScopes(from2, to) {
|
|
2891
|
+
const keys = /* @__PURE__ */ new Set();
|
|
2892
|
+
for (const key of this.entries.keys()) {
|
|
2893
|
+
const scope = key.slice(0, key.indexOf(SCOPE_SEPARATOR));
|
|
2894
|
+
if (scope === (from2 ?? "") || scope === (to ?? "")) keys.add(cacheKeyOf(key));
|
|
2895
|
+
}
|
|
2896
|
+
for (const key of keys) this.notify(key);
|
|
2897
|
+
}
|
|
2791
2898
|
notify(key) {
|
|
2792
2899
|
this.versions.set(key, (this.versions.get(key) ?? 0) + 1);
|
|
2793
2900
|
const subs = this.subscribers.get(key);
|
|
@@ -2804,7 +2911,7 @@ class StagedStore {
|
|
|
2804
2911
|
const settled = prev2.then(op, op).then(
|
|
2805
2912
|
() => void 0,
|
|
2806
2913
|
(err) => {
|
|
2807
|
-
this.emitPersistError(key, err);
|
|
2914
|
+
this.emitPersistError(cacheKeyOf(key), err);
|
|
2808
2915
|
}
|
|
2809
2916
|
).then(() => {
|
|
2810
2917
|
if (this.saveChains.get(key) === settled) this.saveChains.delete(key);
|
|
@@ -2835,11 +2942,18 @@ class StagedStore {
|
|
|
2835
2942
|
return;
|
|
2836
2943
|
}
|
|
2837
2944
|
for (const [key, p2] of persisted) {
|
|
2945
|
+
if (!key.includes(SCOPE_SEPARATOR)) {
|
|
2946
|
+
this.persist(key, () => this.adapter.remove(key));
|
|
2947
|
+
this.emitPersistError(key, new Error(
|
|
2948
|
+
`a staged edit of ${key} that an older build left names no server or repository, and was dropped`
|
|
2949
|
+
));
|
|
2950
|
+
continue;
|
|
2951
|
+
}
|
|
2838
2952
|
this.entries.set(key, {
|
|
2839
2953
|
snapshot: p2.snapshot,
|
|
2840
2954
|
buffered: p2.buffered
|
|
2841
2955
|
});
|
|
2842
|
-
this.notify(key);
|
|
2956
|
+
this.notify(cacheKeyOf(key));
|
|
2843
2957
|
}
|
|
2844
2958
|
}
|
|
2845
2959
|
}
|
|
@@ -2867,7 +2981,7 @@ function clearStagedStoreSingleton() {
|
|
|
2867
2981
|
}
|
|
2868
2982
|
const UNCHANGED_VARIANT = variant("unchanged", null);
|
|
2869
2983
|
const blobEqual = equalFor(BlobType);
|
|
2870
|
-
const eastTypeEqual$
|
|
2984
|
+
const eastTypeEqual$1 = equalFor(EastTypeType);
|
|
2871
2985
|
const helpersCache = new SortedMap(
|
|
2872
2986
|
void 0,
|
|
2873
2987
|
compareFor(EastTypeType)
|
|
@@ -2956,8 +3070,14 @@ class BindRuntime {
|
|
|
2956
3070
|
}
|
|
2957
3071
|
this.cache = cache3;
|
|
2958
3072
|
}
|
|
2959
|
-
/**
|
|
2960
|
-
|
|
3073
|
+
/**
|
|
3074
|
+
* Clear the active cache and drop any queued writes.
|
|
3075
|
+
*
|
|
3076
|
+
* @param cache - Clear only while this is the active cache, so a provider
|
|
3077
|
+
* tearing down after another installed its own leaves that one in place
|
|
3078
|
+
*/
|
|
3079
|
+
clearCache(cache3) {
|
|
3080
|
+
if (cache3 !== void 0 && this.cache !== cache3) return;
|
|
2961
3081
|
this.cache = null;
|
|
2962
3082
|
this.clearPendingWrites();
|
|
2963
3083
|
this.handleCache.clear();
|
|
@@ -3070,11 +3190,11 @@ class BindRuntime {
|
|
|
3070
3190
|
const key = datasetCacheKey(workspace, sourcePath);
|
|
3071
3191
|
const existing = this.bindingRegistry.get(key);
|
|
3072
3192
|
if (existing) {
|
|
3073
|
-
if (existing.mode === info.mode && existing.hasPatchDataset === info.hasPatchDataset && existing.sourceType
|
|
3193
|
+
if (existing.mode === info.mode && existing.hasPatchDataset === info.hasPatchDataset && Object.is(existing.sourceType, info.sourceType)) {
|
|
3074
3194
|
return;
|
|
3075
3195
|
}
|
|
3076
3196
|
const shapeChanged = existing.mode !== info.mode || existing.hasPatchDataset !== info.hasPatchDataset;
|
|
3077
|
-
const typeChanged = !eastTypeEqual$
|
|
3197
|
+
const typeChanged = !eastTypeEqual$1(existing.sourceType, info.sourceType);
|
|
3078
3198
|
if (!shapeChanged && !typeChanged) {
|
|
3079
3199
|
this.bindingRegistry.set(key, info);
|
|
3080
3200
|
return;
|
|
@@ -3264,7 +3384,7 @@ class BindRuntime {
|
|
|
3264
3384
|
};
|
|
3265
3385
|
const bindingDescriptor = {
|
|
3266
3386
|
source: sourcePath,
|
|
3267
|
-
patch: patchPath ?
|
|
3387
|
+
patch: patchPath ? some(patchPath) : none$1,
|
|
3268
3388
|
mode: variant(mode, null)
|
|
3269
3389
|
};
|
|
3270
3390
|
const writeStaged = (value) => {
|
|
@@ -3282,6 +3402,10 @@ class BindRuntime {
|
|
|
3282
3402
|
this.queueWrite(() => cache3.launchDataflow(ws));
|
|
3283
3403
|
return null;
|
|
3284
3404
|
};
|
|
3405
|
+
const hasSource = () => {
|
|
3406
|
+
this.trackPath(ws, sourcePath);
|
|
3407
|
+
return cache3.has(ws, sourcePath);
|
|
3408
|
+
};
|
|
3285
3409
|
if (mode === "direct" && !patchPath) {
|
|
3286
3410
|
return {
|
|
3287
3411
|
read: () => {
|
|
@@ -3304,7 +3428,7 @@ class BindRuntime {
|
|
|
3304
3428
|
pending: () => false,
|
|
3305
3429
|
commit: () => null,
|
|
3306
3430
|
discard: () => null,
|
|
3307
|
-
has:
|
|
3431
|
+
has: hasSource,
|
|
3308
3432
|
status: () => {
|
|
3309
3433
|
this.trackPath(ws, sourcePath);
|
|
3310
3434
|
return cache3.getStatus(ws, sourcePath);
|
|
@@ -3353,7 +3477,7 @@ class BindRuntime {
|
|
|
3353
3477
|
this.queueWrite(() => cache3.write(ws, pPath2, encodePatch(UNCHANGED_VARIANT)));
|
|
3354
3478
|
return null;
|
|
3355
3479
|
},
|
|
3356
|
-
has:
|
|
3480
|
+
has: hasSource,
|
|
3357
3481
|
status: () => {
|
|
3358
3482
|
this.trackPath(ws, sourcePath);
|
|
3359
3483
|
return cache3.getStatus(ws, sourcePath);
|
|
@@ -3397,7 +3521,7 @@ class BindRuntime {
|
|
|
3397
3521
|
staged.discard(ws, sourcePath);
|
|
3398
3522
|
return null;
|
|
3399
3523
|
},
|
|
3400
|
-
has:
|
|
3524
|
+
has: hasSource,
|
|
3401
3525
|
status: () => {
|
|
3402
3526
|
this.trackPath(ws, sourcePath);
|
|
3403
3527
|
return cache3.getStatus(ws, sourcePath);
|
|
@@ -3444,7 +3568,7 @@ class BindRuntime {
|
|
|
3444
3568
|
staged.discard(ws, sourcePath);
|
|
3445
3569
|
return null;
|
|
3446
3570
|
},
|
|
3447
|
-
has:
|
|
3571
|
+
has: hasSource,
|
|
3448
3572
|
status: () => {
|
|
3449
3573
|
this.trackPath(ws, sourcePath);
|
|
3450
3574
|
return cache3.getStatus(ws, sourcePath);
|
|
@@ -3502,8 +3626,8 @@ function getReactiveDatasetCache() {
|
|
|
3502
3626
|
function initializeReactiveDatasetCache(cache3) {
|
|
3503
3627
|
defaultBindRuntime.initializeCache(cache3);
|
|
3504
3628
|
}
|
|
3505
|
-
function clearReactiveDatasetCache() {
|
|
3506
|
-
defaultBindRuntime.clearCache();
|
|
3629
|
+
function clearReactiveDatasetCache(cache3) {
|
|
3630
|
+
defaultBindRuntime.clearCache(cache3);
|
|
3507
3631
|
}
|
|
3508
3632
|
function enableBindingTracking() {
|
|
3509
3633
|
return defaultBindRuntime.enableTracking();
|
|
@@ -3683,7 +3807,11 @@ class TrackedChannelStore {
|
|
|
3683
3807
|
this.keyVersions.clear();
|
|
3684
3808
|
}
|
|
3685
3809
|
}
|
|
3686
|
-
|
|
3810
|
+
const NO_INDEX = { index: null, join: false };
|
|
3811
|
+
function selectorKey(selector2) {
|
|
3812
|
+
return selector2.index === null ? "" : `@${selector2.index}${selector2.join ? "+join" : ""}`;
|
|
3813
|
+
}
|
|
3814
|
+
function createDefaultPagedApi(apiUrl, repo, getToken, datasets) {
|
|
3687
3815
|
const opts = () => ({ token: getToken() });
|
|
3688
3816
|
return {
|
|
3689
3817
|
async getPage(workspace, path2, window3) {
|
|
@@ -3691,58 +3819,115 @@ function createDefaultPagedApi(apiUrl, repo, getToken) {
|
|
|
3691
3819
|
},
|
|
3692
3820
|
async findKey(workspace, path2, query) {
|
|
3693
3821
|
return datasetFindKey(apiUrl, repo, workspace, path2, query, opts());
|
|
3822
|
+
},
|
|
3823
|
+
async getRevision(workspace, path2) {
|
|
3824
|
+
const status = await datasetGetStatus(apiUrl, repo, workspace, path2, opts());
|
|
3825
|
+
return status.hash.type === "some" ? status.hash.value : null;
|
|
3826
|
+
},
|
|
3827
|
+
watchRevision(workspace, path2, onChange2) {
|
|
3828
|
+
return datasets.watchHash(workspace, path2, onChange2);
|
|
3694
3829
|
}
|
|
3695
3830
|
};
|
|
3696
3831
|
}
|
|
3697
3832
|
const RETRY_AFTER_MS = 2e3;
|
|
3698
3833
|
const MAX_RETAINED_WINDOWS = 24;
|
|
3699
|
-
const PERMANENT_PAGE_ERRORS = /* @__PURE__ */ new Set([
|
|
3700
|
-
|
|
3834
|
+
const PERMANENT_PAGE_ERRORS = /* @__PURE__ */ new Set([
|
|
3835
|
+
"bad_request",
|
|
3836
|
+
"dataset_not_canonical",
|
|
3837
|
+
"dataset_not_indexed",
|
|
3838
|
+
"dataset_not_pageable",
|
|
3839
|
+
"dataset_not_searchable",
|
|
3840
|
+
"dataset_not_segmented",
|
|
3841
|
+
"index_not_found",
|
|
3842
|
+
"key_parse_error"
|
|
3843
|
+
]);
|
|
3844
|
+
const NO_VALUE_ERRORS = /* @__PURE__ */ new Set(["dataset_unassigned", "dataset_null"]);
|
|
3845
|
+
function toSelector(indexArg, joinArg) {
|
|
3846
|
+
const index2 = indexArg;
|
|
3847
|
+
return {
|
|
3848
|
+
index: index2 !== void 0 && index2.type === "some" ? index2.value : null,
|
|
3849
|
+
join: joinArg === true
|
|
3850
|
+
};
|
|
3851
|
+
}
|
|
3852
|
+
function checkDeclared(allowed, path2) {
|
|
3853
|
+
if (allowed === null) return;
|
|
3854
|
+
const pathStr = datasetPathToString(path2);
|
|
3855
|
+
if (!allowed.has(pathStr)) {
|
|
3856
|
+
throw new Error(
|
|
3857
|
+
`Data.bindPaged: source path "${pathStr}" not declared in manifest — bind it in the task body so derivation records it`
|
|
3858
|
+
);
|
|
3859
|
+
}
|
|
3860
|
+
}
|
|
3861
|
+
function errorCode(err) {
|
|
3701
3862
|
const code = err == null ? void 0 : err.code;
|
|
3702
|
-
return typeof code === "string"
|
|
3863
|
+
return typeof code === "string" ? code : void 0;
|
|
3864
|
+
}
|
|
3865
|
+
function isPermanentPageError(err) {
|
|
3866
|
+
const code = errorCode(err);
|
|
3867
|
+
return code !== void 0 && PERMANENT_PAGE_ERRORS.has(code);
|
|
3868
|
+
}
|
|
3869
|
+
function failureOf(path2, err) {
|
|
3870
|
+
const code = errorCode(err);
|
|
3871
|
+
const details = err == null ? void 0 : err.details;
|
|
3872
|
+
const reason = code === void 0 ? err instanceof Error ? err.message : String(err) : typeof details === "string" && details !== "" ? `${code}: ${details}` : code;
|
|
3873
|
+
return `Data.bindPaged: ${datasetPathToString(path2)}: ${reason}`;
|
|
3703
3874
|
}
|
|
3704
3875
|
function keyTypeOf(sourceType) {
|
|
3705
3876
|
if (sourceType.type === "Dict") return sourceType.value.key;
|
|
3706
3877
|
if (sourceType.type === "Set") return sourceType.value;
|
|
3707
3878
|
return null;
|
|
3708
3879
|
}
|
|
3709
|
-
function buildSeek(sourceType, T2, pathExpr, platform) {
|
|
3710
|
-
if (keyTypeOf(sourceType) === null) return none$1;
|
|
3880
|
+
function buildSeek(sourceType, T2, pathExpr, indexExpr, joinExpr, selector2, platform) {
|
|
3881
|
+
if (selector2.index === null && keyTypeOf(sourceType) === null) return none$1;
|
|
3711
3882
|
const { seek } = DataPagedPrimitives;
|
|
3712
3883
|
return some(East.compile(
|
|
3713
3884
|
East.function([SeekQueryType], OptionType(SeekRangeType), ($3, query) => {
|
|
3714
|
-
$3.return(seek([T2], pathExpr, query));
|
|
3885
|
+
$3.return(seek([T2], pathExpr, indexExpr, joinExpr, query));
|
|
3715
3886
|
}),
|
|
3716
3887
|
platform
|
|
3717
3888
|
));
|
|
3718
3889
|
}
|
|
3719
|
-
function
|
|
3720
|
-
return `paged:${workspace}:${datasetPathToString(path2)}
|
|
3890
|
+
function pagedRevisionKey(workspace, path2) {
|
|
3891
|
+
return `paged:${workspace}:${datasetPathToString(path2)}#revision`;
|
|
3892
|
+
}
|
|
3893
|
+
function pagedWindowKey(workspace, path2, revision, offset, limit2, selector2 = NO_INDEX) {
|
|
3894
|
+
return `paged:${workspace}:${datasetPathToString(path2)}${selectorKey(selector2)}@${revision}#${offset}+${limit2}`;
|
|
3721
3895
|
}
|
|
3722
|
-
function pagedTotalKey(workspace, path2) {
|
|
3723
|
-
return `paged:${workspace}:${datasetPathToString(path2)}#total`;
|
|
3896
|
+
function pagedTotalKey(workspace, path2, revision, selector2 = NO_INDEX) {
|
|
3897
|
+
return `paged:${workspace}:${datasetPathToString(path2)}${selectorKey(selector2)}@${revision}#total`;
|
|
3724
3898
|
}
|
|
3725
|
-
function pagedSeekKey(workspace, path2, query) {
|
|
3726
|
-
const q = "key" in query ? `k=${query.key}` : "fields" in query ? `f=${query.fields.join("\0")}|p=${query.prefix ?? ""}` : `p=${query.prefix}`;
|
|
3727
|
-
return `paged:${workspace}:${datasetPathToString(path2)}#seek:${q}`;
|
|
3899
|
+
function pagedSeekKey(workspace, path2, revision, query, selector2 = NO_INDEX) {
|
|
3900
|
+
const q = "key" in query ? `k=${query.key}` : "fields" in query ? `f=${query.fields.join("\0")}|p=${query.prefix ?? ""}` : "prefix" in query ? `p=${query.prefix}` : `r=${(query.from ?? []).join("\0")}|${(query.to ?? []).join("\0")}`;
|
|
3901
|
+
return `paged:${workspace}:${datasetPathToString(path2)}${selectorKey(selector2)}@${revision}#seek:${q}`;
|
|
3728
3902
|
}
|
|
3729
|
-
function toFindQuery(query) {
|
|
3903
|
+
function toFindQuery(query, selector2 = NO_INDEX) {
|
|
3730
3904
|
const q = query;
|
|
3731
|
-
|
|
3732
|
-
if (q.type === "
|
|
3905
|
+
const scope = selector2.index === null ? {} : { index: selector2.index };
|
|
3906
|
+
if (q.type === "key") return { key: q.value, ...scope };
|
|
3907
|
+
if (q.type === "prefix") return { prefix: q.value, ...scope };
|
|
3908
|
+
if (q.type === "range") {
|
|
3909
|
+
const r2 = q.value;
|
|
3910
|
+
const from2 = [...r2.from];
|
|
3911
|
+
const to = [...r2.to];
|
|
3912
|
+
if (from2.length === 0 && to.length === 0) {
|
|
3913
|
+
throw new Error("Data.bindPaged: a range seek names no end — give it a `from`, a `to`, or both");
|
|
3914
|
+
}
|
|
3915
|
+
return from2.length === 0 ? { to, ...scope } : to.length === 0 ? { from: from2, ...scope } : { from: from2, to, ...scope };
|
|
3916
|
+
}
|
|
3733
3917
|
const f2 = q.value;
|
|
3734
3918
|
const fields = [...f2.values];
|
|
3735
|
-
return f2.prefix.type === "some" ? { fields, prefix: f2.prefix.value } : { fields };
|
|
3919
|
+
return f2.prefix.type === "some" ? { fields, prefix: f2.prefix.value, ...scope } : { fields, ...scope };
|
|
3736
3920
|
}
|
|
3737
3921
|
class PagedRuntime extends TrackedChannelStore {
|
|
3738
3922
|
constructor() {
|
|
3739
3923
|
super(...arguments);
|
|
3740
3924
|
__publicField(this, "api", null);
|
|
3741
3925
|
__publicField(this, "workspace", null);
|
|
3742
|
-
// Compiled-handle cache (issue #106 perf): buildHandle compiles
|
|
3926
|
+
// Compiled-handle cache (issue #106 perf): buildHandle compiles several
|
|
3743
3927
|
// East.functions per bind, and binds re-run every reactive frame. The
|
|
3744
|
-
// method IR is a pure function of (sourceType,
|
|
3745
|
-
// resolve api/workspace LIVE, so a cached handle still
|
|
3928
|
+
// method IR is a pure function of (sourceType, path, selector, shape), and
|
|
3929
|
+
// the methods resolve api/workspace LIVE, so a cached handle still
|
|
3930
|
+
// re-binds.
|
|
3746
3931
|
//
|
|
3747
3932
|
// Keyed by TYPE first, then path — never by path alone. The window decoder
|
|
3748
3933
|
// is baked from `sourceType`, so a path re-bound at a different type (a
|
|
@@ -3757,6 +3942,10 @@ class PagedRuntime extends TrackedChannelStore {
|
|
|
3757
3942
|
/** Loaded window keys in least-recently-READ order (a Map preserves
|
|
3758
3943
|
* insertion order; a read re-inserts). Bounds the decoded-window cache. */
|
|
3759
3944
|
__publicField(this, "loadedWindows", /* @__PURE__ */ new Map());
|
|
3945
|
+
/** Each dataset's snapshot, by workspace and path. */
|
|
3946
|
+
__publicField(this, "snapshots", /* @__PURE__ */ new Map());
|
|
3947
|
+
/** Fetches launched so far — the source of every channel's `launchSeq`. */
|
|
3948
|
+
__publicField(this, "launches", 0);
|
|
3760
3949
|
}
|
|
3761
3950
|
/** Monotonic clock seam so tests can drive the retry gate. */
|
|
3762
3951
|
now() {
|
|
@@ -3767,17 +3956,33 @@ class PagedRuntime extends TrackedChannelStore {
|
|
|
3767
3956
|
}
|
|
3768
3957
|
// ----- wiring ----------------------------------------------------------
|
|
3769
3958
|
/** Install the API adapter + workspace — called by the React provider
|
|
3770
|
-
* (or a test/showcase harness) before any handle is used.
|
|
3959
|
+
* (or a test/showcase harness) before any handle is used. Another adapter
|
|
3960
|
+
* or workspace starts from nothing: no snapshot of the old one's carries
|
|
3961
|
+
* over. */
|
|
3771
3962
|
initialize(api3, workspace) {
|
|
3963
|
+
if (this.api !== api3 || this.workspace !== workspace) this.reset();
|
|
3772
3964
|
this.api = api3;
|
|
3773
3965
|
this.workspace = workspace;
|
|
3774
3966
|
}
|
|
3775
|
-
/**
|
|
3776
|
-
|
|
3967
|
+
/**
|
|
3968
|
+
* Tear down the adapter and all window state.
|
|
3969
|
+
*
|
|
3970
|
+
* @param api - Clear only while this is the installed adapter, so a
|
|
3971
|
+
* provider tearing down after another installed its own leaves that one
|
|
3972
|
+
* in place
|
|
3973
|
+
*/
|
|
3974
|
+
clear(api3) {
|
|
3975
|
+
if (api3 !== void 0 && this.api !== api3) return;
|
|
3777
3976
|
this.api = null;
|
|
3778
3977
|
this.workspace = null;
|
|
3779
|
-
this.
|
|
3978
|
+
this.reset();
|
|
3780
3979
|
this.handleCache.clear();
|
|
3980
|
+
}
|
|
3981
|
+
/** Stop following every dataset, and drop what every snapshot delivered. */
|
|
3982
|
+
reset() {
|
|
3983
|
+
for (const snapshot of this.snapshots.values()) snapshot.unwatch();
|
|
3984
|
+
this.snapshots.clear();
|
|
3985
|
+
this.clearChannels();
|
|
3781
3986
|
this.loadedWindows.clear();
|
|
3782
3987
|
}
|
|
3783
3988
|
resolveWorkspace() {
|
|
@@ -3788,7 +3993,178 @@ class PagedRuntime extends TrackedChannelStore {
|
|
|
3788
3993
|
}
|
|
3789
3994
|
return this.workspace;
|
|
3790
3995
|
}
|
|
3791
|
-
// -----
|
|
3996
|
+
// ----- snapshots -------------------------------------------------------
|
|
3997
|
+
/** A dataset's snapshot, followed from its first read until the runtime
|
|
3998
|
+
* is cleared. */
|
|
3999
|
+
snapshotOf(workspace, path2) {
|
|
4000
|
+
const key = `${workspace}:${datasetPathToString(path2)}`;
|
|
4001
|
+
const existing = this.snapshots.get(key);
|
|
4002
|
+
if (existing !== void 0) return existing;
|
|
4003
|
+
const snapshot = {
|
|
4004
|
+
key,
|
|
4005
|
+
revision: void 0,
|
|
4006
|
+
moves: 0,
|
|
4007
|
+
findSeq: 0,
|
|
4008
|
+
finding: false,
|
|
4009
|
+
channels: /* @__PURE__ */ new Set(),
|
|
4010
|
+
unwatch: () => {
|
|
4011
|
+
}
|
|
4012
|
+
};
|
|
4013
|
+
this.snapshots.set(key, snapshot);
|
|
4014
|
+
if (this.api !== null) {
|
|
4015
|
+
snapshot.unwatch = this.api.watchRevision(workspace, path2, (hash2) => this.moveTo(workspace, path2, snapshot, hash2));
|
|
4016
|
+
}
|
|
4017
|
+
return snapshot;
|
|
4018
|
+
}
|
|
4019
|
+
/** Whether a snapshot is still the runtime's, rather than one a clear or a
|
|
4020
|
+
* re-initialization dropped. */
|
|
4021
|
+
isLive(snapshot) {
|
|
4022
|
+
return this.snapshots.get(snapshot.key) === snapshot;
|
|
4023
|
+
}
|
|
4024
|
+
/** Whether a live snapshot is still pinned to `revision`. */
|
|
4025
|
+
pinnedTo(snapshot, revision) {
|
|
4026
|
+
return this.isLive(snapshot) && snapshot.revision === revision;
|
|
4027
|
+
}
|
|
4028
|
+
/**
|
|
4029
|
+
* The revision a read of `path` is pinned to — a hash, `null` while the
|
|
4030
|
+
* dataset has no value, or `undefined` while it is being found — tracked so
|
|
4031
|
+
* the read re-fires when the source moves.
|
|
4032
|
+
*
|
|
4033
|
+
* @throws The failed lookup's reason, until a read after the retry gap
|
|
4034
|
+
* looks again
|
|
4035
|
+
*/
|
|
4036
|
+
revisionFor(workspace, path2) {
|
|
4037
|
+
this.track(pagedRevisionKey(workspace, path2));
|
|
4038
|
+
const snapshot = this.snapshotOf(workspace, path2);
|
|
4039
|
+
if (snapshot.revision !== void 0 || snapshot.finding) return snapshot.revision;
|
|
4040
|
+
if (snapshot.findError !== void 0 && this.now() - (snapshot.findFailedAtMs ?? 0) < RETRY_AFTER_MS) {
|
|
4041
|
+
throw new Error(snapshot.findError);
|
|
4042
|
+
}
|
|
4043
|
+
this.find(workspace, path2, snapshot);
|
|
4044
|
+
return void 0;
|
|
4045
|
+
}
|
|
4046
|
+
/**
|
|
4047
|
+
* Ask the server which content the dataset holds, and move there — unless
|
|
4048
|
+
* a move lands first, which came from something no older than the answer.
|
|
4049
|
+
*/
|
|
4050
|
+
find(workspace, path2, snapshot) {
|
|
4051
|
+
const seq = ++snapshot.findSeq;
|
|
4052
|
+
const moves = snapshot.moves;
|
|
4053
|
+
snapshot.finding = true;
|
|
4054
|
+
const api3 = this.api;
|
|
4055
|
+
void (async () => {
|
|
4056
|
+
let revision;
|
|
4057
|
+
try {
|
|
4058
|
+
if (api3 === null) throw new Error("no PagedApi installed");
|
|
4059
|
+
revision = await api3.getRevision(workspace, path2);
|
|
4060
|
+
} catch (err) {
|
|
4061
|
+
if (!this.isLive(snapshot) || snapshot.findSeq !== seq) return;
|
|
4062
|
+
snapshot.finding = false;
|
|
4063
|
+
if (snapshot.revision !== void 0) return;
|
|
4064
|
+
snapshot.findError = failureOf(path2, err);
|
|
4065
|
+
snapshot.findFailedAtMs = this.now();
|
|
4066
|
+
console.error(`Data.bindPaged: could not find which content ${datasetPathToString(path2)} holds:`, err);
|
|
4067
|
+
this.notify(pagedRevisionKey(workspace, path2));
|
|
4068
|
+
return;
|
|
4069
|
+
}
|
|
4070
|
+
if (!this.isLive(snapshot) || snapshot.findSeq !== seq) return;
|
|
4071
|
+
snapshot.finding = false;
|
|
4072
|
+
if (snapshot.moves !== moves) return;
|
|
4073
|
+
this.moveTo(workspace, path2, snapshot, revision);
|
|
4074
|
+
})();
|
|
4075
|
+
}
|
|
4076
|
+
/**
|
|
4077
|
+
* Move a dataset's source to `revision`: drop what the old snapshot
|
|
4078
|
+
* delivered and re-fire every read of the dataset, so the windows and
|
|
4079
|
+
* searches still in use are fetched again, pinned to the new one. A move to
|
|
4080
|
+
* the revision the source already has changes nothing.
|
|
4081
|
+
*/
|
|
4082
|
+
moveTo(workspace, path2, snapshot, revision) {
|
|
4083
|
+
if (!this.isLive(snapshot) || snapshot.revision === revision) return;
|
|
4084
|
+
snapshot.revision = revision;
|
|
4085
|
+
snapshot.moves += 1;
|
|
4086
|
+
delete snapshot.findError;
|
|
4087
|
+
delete snapshot.findFailedAtMs;
|
|
4088
|
+
for (const key of snapshot.channels) {
|
|
4089
|
+
this.entries.delete(key);
|
|
4090
|
+
this.loadedWindows.delete(key);
|
|
4091
|
+
}
|
|
4092
|
+
snapshot.channels.clear();
|
|
4093
|
+
this.notify(pagedRevisionKey(workspace, path2));
|
|
4094
|
+
}
|
|
4095
|
+
/**
|
|
4096
|
+
* Handle what a pinned fetch threw when it is not the read's failure: a
|
|
4097
|
+
* refusal naming other content moves the source there, and "no value"
|
|
4098
|
+
* moves it to no snapshot. Returns whether the error was one of those, or
|
|
4099
|
+
* arrived after the source had already moved on.
|
|
4100
|
+
*/
|
|
4101
|
+
followed(workspace, path2, snapshot, revision, err) {
|
|
4102
|
+
if (!this.pinnedTo(snapshot, revision)) return true;
|
|
4103
|
+
if (err instanceof DatasetHashMismatchError) {
|
|
4104
|
+
if (err.currentHash !== null && err.currentHash !== revision) {
|
|
4105
|
+
this.moveTo(workspace, path2, snapshot, err.currentHash);
|
|
4106
|
+
return true;
|
|
4107
|
+
}
|
|
4108
|
+
this.find(workspace, path2, snapshot);
|
|
4109
|
+
return false;
|
|
4110
|
+
}
|
|
4111
|
+
const code = errorCode(err);
|
|
4112
|
+
if (code !== void 0 && NO_VALUE_ERRORS.has(code)) {
|
|
4113
|
+
this.moveTo(workspace, path2, snapshot, null);
|
|
4114
|
+
return true;
|
|
4115
|
+
}
|
|
4116
|
+
return false;
|
|
4117
|
+
}
|
|
4118
|
+
// ----- channels ----------------------------------------------------------
|
|
4119
|
+
/** A channel of the snapshot's current revision, dropped when it moves. */
|
|
4120
|
+
channel(snapshot, key) {
|
|
4121
|
+
snapshot.channels.add(key);
|
|
4122
|
+
return this.entry(key);
|
|
4123
|
+
}
|
|
4124
|
+
/** Whether a channel is due a fetch: never fetched, evicted, or failed
|
|
4125
|
+
* for a reason a retry can fix, longer ago than the retry gap. */
|
|
4126
|
+
due(entry) {
|
|
4127
|
+
if (entry.status === "idle") return true;
|
|
4128
|
+
if (entry.status !== "failed" || entry.permanent === true) return false;
|
|
4129
|
+
return this.now() - (entry.failedAtMs ?? 0) >= RETRY_AFTER_MS;
|
|
4130
|
+
}
|
|
4131
|
+
/**
|
|
4132
|
+
* Mark a channel's fetch as started, returning the fetch's sequence number.
|
|
4133
|
+
*
|
|
4134
|
+
* Deliberately does NOT notify — the read that triggers it runs inside a
|
|
4135
|
+
* render pass, and notifying there would re-enter the renderer. Only the
|
|
4136
|
+
* settle notifies.
|
|
4137
|
+
*/
|
|
4138
|
+
launch(entry) {
|
|
4139
|
+
entry.status = "running";
|
|
4140
|
+
entry.launchSeq = ++this.launches;
|
|
4141
|
+
return entry.launchSeq;
|
|
4142
|
+
}
|
|
4143
|
+
/** Apply a fetch's outcome if the channel still waits on it, re-firing the
|
|
4144
|
+
* channel's reads. Returns whether it applied. */
|
|
4145
|
+
settle(key, seq, mutate) {
|
|
4146
|
+
const entry = this.entries.get(key);
|
|
4147
|
+
if (entry === void 0 || entry.launchSeq !== seq) return false;
|
|
4148
|
+
mutate(entry);
|
|
4149
|
+
this.notify(key);
|
|
4150
|
+
return true;
|
|
4151
|
+
}
|
|
4152
|
+
/** Settle a fetch as failed, with the reason a read will throw. */
|
|
4153
|
+
fail(key, seq, reason, permanent) {
|
|
4154
|
+
this.settle(key, seq, (e3) => {
|
|
4155
|
+
e3.status = "failed";
|
|
4156
|
+
e3.error = reason;
|
|
4157
|
+
e3.failedAtMs = this.now();
|
|
4158
|
+
e3.permanent = permanent;
|
|
4159
|
+
});
|
|
4160
|
+
}
|
|
4161
|
+
/** What a read of a channel answers: its value once loaded, `none` while
|
|
4162
|
+
* in flight, or its failure, thrown. */
|
|
4163
|
+
answer(entry, value) {
|
|
4164
|
+
if (entry.status === "loaded" && value !== void 0) return some(value);
|
|
4165
|
+
if (entry.status === "failed") throw new Error(entry.error ?? "Data.bindPaged: the read failed");
|
|
4166
|
+
return none$1;
|
|
4167
|
+
}
|
|
3792
4168
|
/** Note a window as most-recently-read, and drop the coldest decoded
|
|
3793
4169
|
* windows once the cache exceeds its cap. An evicted window returns to
|
|
3794
4170
|
* `idle`, so the next read refetches it rather than reading a hole. */
|
|
@@ -3806,131 +4182,83 @@ class PagedRuntime extends TrackedChannelStore {
|
|
|
3806
4182
|
delete entry.window;
|
|
3807
4183
|
}
|
|
3808
4184
|
}
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
*
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
ensureWindow(sourceType, workspace, path2, offset, limit2) {
|
|
3817
|
-
const key = pagedWindowKey(workspace, path2, offset, limit2);
|
|
3818
|
-
const entry = this.entry(key);
|
|
3819
|
-
if (entry.status === "running" || entry.status === "loaded") return;
|
|
3820
|
-
if (entry.status === "failed") {
|
|
3821
|
-
if (entry.permanent) return;
|
|
3822
|
-
const since = this.now() - (entry.failedAtMs ?? 0);
|
|
3823
|
-
if (since < RETRY_AFTER_MS) return;
|
|
3824
|
-
}
|
|
3825
|
-
entry.status = "running";
|
|
3826
|
-
entry.launchSeq += 1;
|
|
3827
|
-
const mySeq = entry.launchSeq;
|
|
4185
|
+
// ----- window loading --------------------------------------------------
|
|
4186
|
+
/** Start the pinned fetch for a window if it is due one, returning its
|
|
4187
|
+
* channel. */
|
|
4188
|
+
ensureWindow(sourceType, workspace, path2, snapshot, revision, offset, limit2, selector2, key) {
|
|
4189
|
+
const entry = this.channel(snapshot, key);
|
|
4190
|
+
if (!this.due(entry)) return entry;
|
|
4191
|
+
const seq = this.launch(entry);
|
|
3828
4192
|
const api3 = this.api;
|
|
3829
4193
|
void (async () => {
|
|
3830
|
-
const settle = (mutate) => {
|
|
3831
|
-
const current = this.entries.get(key);
|
|
3832
|
-
if (!current || current.launchSeq !== mySeq) return;
|
|
3833
|
-
mutate(current);
|
|
3834
|
-
this.notify(key);
|
|
3835
|
-
};
|
|
3836
|
-
if (!api3) {
|
|
3837
|
-
settle((e3) => {
|
|
3838
|
-
e3.status = "failed";
|
|
3839
|
-
e3.failedAtMs = this.now();
|
|
3840
|
-
});
|
|
3841
|
-
console.error("Data.bindPaged: no PagedApi installed");
|
|
3842
|
-
return;
|
|
3843
|
-
}
|
|
3844
4194
|
let page;
|
|
3845
4195
|
try {
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
e3.permanent = permanent;
|
|
4196
|
+
if (api3 === null) throw new Error("no PagedApi installed");
|
|
4197
|
+
page = await api3.getPage(workspace, path2, {
|
|
4198
|
+
offset,
|
|
4199
|
+
limit: limit2,
|
|
4200
|
+
hash: revision,
|
|
4201
|
+
...selector2.index !== null && { index: selector2.index, join: selector2.join }
|
|
3853
4202
|
});
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
|
|
3857
|
-
);
|
|
4203
|
+
} catch (err) {
|
|
4204
|
+
if (this.followed(workspace, path2, snapshot, revision, err)) return;
|
|
4205
|
+
this.fail(key, seq, failureOf(path2, err), isPermanentPageError(err));
|
|
4206
|
+
console.error(`Data.bindPaged: fetch failed for ${key}:`, err);
|
|
3858
4207
|
return;
|
|
3859
4208
|
}
|
|
4209
|
+
if (!this.pinnedTo(snapshot, revision)) return;
|
|
3860
4210
|
let decoded;
|
|
3861
4211
|
try {
|
|
3862
4212
|
decoded = decodeBeast2For(sourceType)(page.data);
|
|
3863
4213
|
} catch (err) {
|
|
3864
|
-
|
|
3865
|
-
e3.status = "failed";
|
|
3866
|
-
e3.failedAtMs = this.now();
|
|
3867
|
-
});
|
|
4214
|
+
this.fail(key, seq, `${failureOf(path2, err)} (the window does not decode as the source's type)`, true);
|
|
3868
4215
|
console.error(`Data.bindPaged: decode failed for ${key}:`, err);
|
|
3869
4216
|
return;
|
|
3870
4217
|
}
|
|
3871
|
-
settle((e3) => {
|
|
4218
|
+
const landed = this.settle(key, seq, (e3) => {
|
|
3872
4219
|
e3.status = "loaded";
|
|
3873
4220
|
e3.window = decoded;
|
|
3874
4221
|
e3.total = page.totalElements;
|
|
4222
|
+
delete e3.error;
|
|
3875
4223
|
});
|
|
4224
|
+
if (!landed) return;
|
|
3876
4225
|
this.touchWindow(key);
|
|
3877
|
-
const totalKey = pagedTotalKey(workspace, path2);
|
|
3878
|
-
const totalEntry = this.
|
|
4226
|
+
const totalKey = pagedTotalKey(workspace, path2, revision, selector2);
|
|
4227
|
+
const totalEntry = this.channel(snapshot, totalKey);
|
|
3879
4228
|
if (totalEntry.total !== page.totalElements) {
|
|
3880
4229
|
totalEntry.total = page.totalElements;
|
|
3881
4230
|
totalEntry.status = "loaded";
|
|
3882
4231
|
this.notify(totalKey);
|
|
3883
4232
|
}
|
|
3884
4233
|
})();
|
|
4234
|
+
return entry;
|
|
3885
4235
|
}
|
|
3886
|
-
/**
|
|
3887
|
-
*
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
const entry = this.entry(key);
|
|
3893
|
-
if (entry.status === "running" || entry.status === "loaded") return;
|
|
3894
|
-
if (entry.status === "failed") {
|
|
3895
|
-
if (entry.permanent) return;
|
|
3896
|
-
const since = this.now() - (entry.failedAtMs ?? 0);
|
|
3897
|
-
if (since < RETRY_AFTER_MS) return;
|
|
3898
|
-
}
|
|
3899
|
-
entry.status = "running";
|
|
3900
|
-
entry.launchSeq += 1;
|
|
3901
|
-
const mySeq = entry.launchSeq;
|
|
4236
|
+
/** Start the pinned fence search for one key query if it is due one,
|
|
4237
|
+
* returning its channel — the seek sibling of {@link ensureWindow}. */
|
|
4238
|
+
ensureSeek(workspace, path2, snapshot, revision, query, key) {
|
|
4239
|
+
const entry = this.channel(snapshot, key);
|
|
4240
|
+
if (!this.due(entry)) return entry;
|
|
4241
|
+
const seq = this.launch(entry);
|
|
3902
4242
|
const api3 = this.api;
|
|
3903
4243
|
void (async () => {
|
|
3904
|
-
|
|
3905
|
-
const current = this.entries.get(key);
|
|
3906
|
-
if (!current || current.launchSeq !== mySeq) return;
|
|
3907
|
-
mutate(current);
|
|
3908
|
-
this.notify(key);
|
|
3909
|
-
};
|
|
3910
|
-
if (!api3) {
|
|
3911
|
-
settle((e3) => {
|
|
3912
|
-
e3.status = "failed";
|
|
3913
|
-
e3.failedAtMs = this.now();
|
|
3914
|
-
});
|
|
3915
|
-
console.error("Data.bindPaged: no PagedApi installed");
|
|
3916
|
-
return;
|
|
3917
|
-
}
|
|
4244
|
+
let range;
|
|
3918
4245
|
try {
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
e3.status = "loaded";
|
|
3922
|
-
e3.range = range;
|
|
3923
|
-
});
|
|
4246
|
+
if (api3 === null) throw new Error("no PagedApi installed");
|
|
4247
|
+
range = await api3.findKey(workspace, path2, { ...query, hash: revision });
|
|
3924
4248
|
} catch (err) {
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
e3.status = "failed";
|
|
3928
|
-
e3.failedAtMs = this.now();
|
|
3929
|
-
e3.permanent = permanent;
|
|
3930
|
-
});
|
|
4249
|
+
if (this.followed(workspace, path2, snapshot, revision, err)) return;
|
|
4250
|
+
this.fail(key, seq, failureOf(path2, err), isPermanentPageError(err));
|
|
3931
4251
|
console.error(`Data.bindPaged: key search failed for ${key}:`, err);
|
|
4252
|
+
return;
|
|
3932
4253
|
}
|
|
4254
|
+
if (!this.pinnedTo(snapshot, revision)) return;
|
|
4255
|
+
this.settle(key, seq, (e3) => {
|
|
4256
|
+
e3.status = "loaded";
|
|
4257
|
+
e3.range = range;
|
|
4258
|
+
delete e3.error;
|
|
4259
|
+
});
|
|
3933
4260
|
})();
|
|
4261
|
+
return entry;
|
|
3934
4262
|
}
|
|
3935
4263
|
/**
|
|
3936
4264
|
* The low-level primitives backing handle methods, bound to THIS runtime.
|
|
@@ -3940,53 +4268,92 @@ class PagedRuntime extends TrackedChannelStore {
|
|
|
3940
4268
|
*/
|
|
3941
4269
|
buildPrimitives() {
|
|
3942
4270
|
return [
|
|
3943
|
-
DataPagedPrimitives.page.implement((sourceType) => (pathArg, offsetArg, limitArg) => {
|
|
4271
|
+
DataPagedPrimitives.page.implement((sourceType) => (pathArg, indexArg, joinArg, offsetArg, limitArg) => {
|
|
3944
4272
|
const workspace = this.resolveWorkspace();
|
|
3945
4273
|
const path2 = pathArg;
|
|
4274
|
+
const revision = this.revisionFor(workspace, path2);
|
|
4275
|
+
if (typeof revision !== "string") return none$1;
|
|
4276
|
+
const selector2 = toSelector(indexArg, joinArg);
|
|
3946
4277
|
const offset = Number(offsetArg);
|
|
3947
4278
|
const limit2 = Number(limitArg);
|
|
3948
|
-
const key = pagedWindowKey(workspace, path2, offset, limit2);
|
|
4279
|
+
const key = pagedWindowKey(workspace, path2, revision, offset, limit2, selector2);
|
|
3949
4280
|
this.track(key);
|
|
3950
|
-
this.ensureWindow(
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
4281
|
+
const entry = this.ensureWindow(
|
|
4282
|
+
sourceType,
|
|
4283
|
+
workspace,
|
|
4284
|
+
path2,
|
|
4285
|
+
this.snapshotOf(workspace, path2),
|
|
4286
|
+
revision,
|
|
4287
|
+
offset,
|
|
4288
|
+
limit2,
|
|
4289
|
+
selector2,
|
|
4290
|
+
key
|
|
4291
|
+
);
|
|
4292
|
+
if (entry.status === "loaded" && entry.window !== void 0) this.touchWindow(key);
|
|
4293
|
+
return this.answer(entry, entry.window);
|
|
3957
4294
|
}),
|
|
3958
|
-
DataPagedPrimitives.total.implement((_sourceType) => (pathArg) => {
|
|
4295
|
+
DataPagedPrimitives.total.implement((_sourceType) => (pathArg, indexArg, joinArg) => {
|
|
3959
4296
|
const workspace = this.resolveWorkspace();
|
|
3960
|
-
const
|
|
4297
|
+
const path2 = pathArg;
|
|
4298
|
+
const revision = this.revisionFor(workspace, path2);
|
|
4299
|
+
if (typeof revision !== "string") return none$1;
|
|
4300
|
+
const key = pagedTotalKey(workspace, path2, revision, toSelector(indexArg, joinArg));
|
|
3961
4301
|
this.track(key);
|
|
3962
|
-
const entry = this.
|
|
3963
|
-
return entry.total !== void 0 ?
|
|
4302
|
+
const entry = this.channel(this.snapshotOf(workspace, path2), key);
|
|
4303
|
+
return entry.total !== void 0 ? some(BigInt(entry.total)) : none$1;
|
|
3964
4304
|
}),
|
|
3965
|
-
DataPagedPrimitives.seek.implement((_sourceType) => (pathArg, queryArg) => {
|
|
4305
|
+
DataPagedPrimitives.seek.implement((_sourceType) => (pathArg, indexArg, joinArg, queryArg) => {
|
|
3966
4306
|
const workspace = this.resolveWorkspace();
|
|
3967
4307
|
const path2 = pathArg;
|
|
3968
|
-
const
|
|
3969
|
-
|
|
4308
|
+
const revision = this.revisionFor(workspace, path2);
|
|
4309
|
+
if (typeof revision !== "string") return none$1;
|
|
4310
|
+
const selector2 = toSelector(indexArg, joinArg);
|
|
4311
|
+
const query = toFindQuery(queryArg, selector2);
|
|
4312
|
+
const key = pagedSeekKey(workspace, path2, revision, query, selector2);
|
|
3970
4313
|
this.track(key);
|
|
3971
|
-
this.ensureSeek(workspace, path2, query, key);
|
|
3972
|
-
const
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
4314
|
+
const entry = this.ensureSeek(workspace, path2, this.snapshotOf(workspace, path2), revision, query, key);
|
|
4315
|
+
const range = entry.range;
|
|
4316
|
+
return this.answer(entry, range === void 0 ? void 0 : { found: range.found, row: BigInt(range.row), count: BigInt(range.count) });
|
|
4317
|
+
}),
|
|
4318
|
+
DataPagedPrimitives.revision.implement((_sourceType) => (pathArg, _indexArg, _joinArg) => {
|
|
4319
|
+
const revision = this.revisionFor(this.resolveWorkspace(), pathArg);
|
|
4320
|
+
return typeof revision === "string" ? some(revision) : none$1;
|
|
4321
|
+
}),
|
|
4322
|
+
DataPagedPrimitives.refresh.implement((_sourceType) => (pathArg, _indexArg, _joinArg, targetArg) => {
|
|
4323
|
+
const workspace = this.resolveWorkspace();
|
|
4324
|
+
const path2 = pathArg;
|
|
4325
|
+
const target = targetArg;
|
|
4326
|
+
queueMicrotask(() => {
|
|
4327
|
+
if (this.workspace !== workspace) return;
|
|
4328
|
+
const snapshot = this.snapshotOf(workspace, path2);
|
|
4329
|
+
if (target.type === "some") this.moveTo(workspace, path2, snapshot, target.value);
|
|
4330
|
+
else this.find(workspace, path2, snapshot);
|
|
4331
|
+
});
|
|
4332
|
+
return null;
|
|
3976
4333
|
})
|
|
3977
4334
|
];
|
|
3978
4335
|
}
|
|
3979
4336
|
/**
|
|
3980
|
-
* Build the handle value for one
|
|
3981
|
-
*
|
|
3982
|
-
*
|
|
3983
|
-
* type-arg) — so the handle is ordinary serializable East data (issue
|
|
4337
|
+
* Build the handle value for one paged bind. Every method is a thin
|
|
4338
|
+
* IR-bearing `East.function` over {@link buildPrimitives}, capturing only
|
|
4339
|
+
* the plain-data source path and selector (the value type rides as a
|
|
4340
|
+
* type-arg) — so the handle is ordinary serializable East data (issue
|
|
4341
|
+
* #106).
|
|
4342
|
+
*
|
|
4343
|
+
* @param sourceType - The dataset's type, or an index's window type
|
|
4344
|
+
* @param path - The dataset's path
|
|
4345
|
+
* @param selector - The rows the bind serves
|
|
4346
|
+
* @param shape - `released`: the handle `data_bind_paged` returns, without
|
|
4347
|
+
* `revision` or `refresh`; `pinned`: the handle `data_bind_paged_pinned`
|
|
4348
|
+
* returns. Both read through the same snapshot.
|
|
4349
|
+
* @returns The handle
|
|
3984
4350
|
*/
|
|
3985
|
-
buildHandle(sourceType, path2) {
|
|
3986
|
-
const
|
|
4351
|
+
buildHandle(sourceType, path2, selector2, shape) {
|
|
4352
|
+
const id3 = `${datasetPathToString(path2)}${selectorKey(selector2)}`;
|
|
4353
|
+
const cacheKey = `${id3}#${shape}`;
|
|
3987
4354
|
let byPath = this.handleCache.get(sourceType);
|
|
3988
4355
|
if (byPath) {
|
|
3989
|
-
const hit = byPath.get(
|
|
4356
|
+
const hit = byPath.get(cacheKey);
|
|
3990
4357
|
if (hit) return hit;
|
|
3991
4358
|
} else {
|
|
3992
4359
|
byPath = /* @__PURE__ */ new Map();
|
|
@@ -3994,24 +4361,27 @@ class PagedRuntime extends TrackedChannelStore {
|
|
|
3994
4361
|
}
|
|
3995
4362
|
const T2 = fromEastTypeValue(sourceType);
|
|
3996
4363
|
const pathExpr = East.value(path2, TreePathType);
|
|
4364
|
+
const indexExpr = East.value(selector2.index === null ? none$1 : some(selector2.index), OptionType(StringType));
|
|
4365
|
+
const joinExpr = East.value(selector2.join, BooleanType);
|
|
3997
4366
|
const platform = this.buildPrimitives();
|
|
3998
|
-
const { page, total } = DataPagedPrimitives;
|
|
4367
|
+
const { page, total, revision, refresh } = DataPagedPrimitives;
|
|
3999
4368
|
const handle = {
|
|
4000
4369
|
// The comparable identity east-ui's `PagedSourceType` requires:
|
|
4001
4370
|
// East compares every function as EQUAL, so a struct of nothing but
|
|
4002
4371
|
// closures is indistinguishable from any other and a memoized
|
|
4003
4372
|
// component would never re-render on a source swap (#567 D4). The
|
|
4004
|
-
// dataset path
|
|
4005
|
-
|
|
4373
|
+
// dataset path and selector are the natural identity — same path,
|
|
4374
|
+
// same rows. The snapshot they serve is `revision`'s, not the id's.
|
|
4375
|
+
id: id3,
|
|
4006
4376
|
page: East.compile(
|
|
4007
4377
|
East.function([IntegerType, IntegerType], OptionType(T2), ($3, offset, limit2) => {
|
|
4008
|
-
$3.return(page([T2], pathExpr, offset, limit2));
|
|
4378
|
+
$3.return(page([T2], pathExpr, indexExpr, joinExpr, offset, limit2));
|
|
4009
4379
|
}),
|
|
4010
4380
|
platform
|
|
4011
4381
|
),
|
|
4012
4382
|
total: East.compile(
|
|
4013
4383
|
East.function([], OptionType(IntegerType), ($3) => {
|
|
4014
|
-
$3.return(total([T2], pathExpr));
|
|
4384
|
+
$3.return(total([T2], pathExpr, indexExpr, joinExpr));
|
|
4015
4385
|
}),
|
|
4016
4386
|
platform
|
|
4017
4387
|
),
|
|
@@ -4020,28 +4390,50 @@ class PagedRuntime extends TrackedChannelStore {
|
|
|
4020
4390
|
// segments) against the stored fences; an Array's stream order has
|
|
4021
4391
|
// nothing to search. Resolved at bind time from the dataset's own
|
|
4022
4392
|
// type, so a component renders the affordance only when it works.
|
|
4023
|
-
seek: buildSeek(sourceType, T2, pathExpr, platform)
|
|
4393
|
+
seek: buildSeek(sourceType, T2, pathExpr, indexExpr, joinExpr, selector2, platform)
|
|
4024
4394
|
};
|
|
4025
|
-
|
|
4395
|
+
if (shape === "pinned") {
|
|
4396
|
+
handle.revision = East.compile(
|
|
4397
|
+
East.function([], OptionType(StringType), ($3) => {
|
|
4398
|
+
$3.return(revision([T2], pathExpr, indexExpr, joinExpr));
|
|
4399
|
+
}),
|
|
4400
|
+
platform
|
|
4401
|
+
);
|
|
4402
|
+
handle.refresh = East.compile(
|
|
4403
|
+
East.function([OptionType(StringType)], NullType, ($3, target) => {
|
|
4404
|
+
$3.return(refresh([T2], pathExpr, indexExpr, joinExpr, target));
|
|
4405
|
+
}),
|
|
4406
|
+
platform
|
|
4407
|
+
);
|
|
4408
|
+
}
|
|
4409
|
+
byPath.set(cacheKey, handle);
|
|
4026
4410
|
return handle;
|
|
4027
4411
|
}
|
|
4028
4412
|
// ----- platform building -------------------------------------------------
|
|
4029
|
-
/** Build
|
|
4030
|
-
*
|
|
4031
|
-
*
|
|
4413
|
+
/** Build the PlatformFunction behind `data_bind_paged` — the bind a UI
|
|
4414
|
+
* exported before pinned reads calls — bound to this runtime. Its handle
|
|
4415
|
+
* has no `revision` or `refresh`, but its reads are pinned, follow the
|
|
4416
|
+
* dataset and fail visibly all the same. Pass `allowed=null` for an
|
|
4417
|
+
* unscoped impl, or a Set of path strings for manifest scoping. */
|
|
4032
4418
|
buildPlatform(allowed) {
|
|
4033
4419
|
return bindPagedPlatformFn.implement(
|
|
4034
4420
|
(sourceType) => (pathArg) => {
|
|
4035
4421
|
const path2 = pathArg;
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4422
|
+
checkDeclared(allowed, path2);
|
|
4423
|
+
return this.buildHandle(sourceType, path2, NO_INDEX, "released");
|
|
4424
|
+
}
|
|
4425
|
+
);
|
|
4426
|
+
}
|
|
4427
|
+
/** Build the PlatformFunction behind `data_bind_paged_pinned` — what
|
|
4428
|
+
* `Data.bindPaged` emits, for a dataset's own rows or a record's index —
|
|
4429
|
+
* bound to this runtime and scoped by `allowed` exactly as
|
|
4430
|
+
* {@link buildPlatform} is: an index read is a read of the record's path. */
|
|
4431
|
+
buildPinnedPlatform(allowed) {
|
|
4432
|
+
return bindPagedPinnedPlatformFn.implement(
|
|
4433
|
+
(sourceType) => (pathArg, indexArg, joinArg) => {
|
|
4434
|
+
const path2 = pathArg;
|
|
4435
|
+
checkDeclared(allowed, path2);
|
|
4436
|
+
return this.buildHandle(sourceType, path2, toSelector(indexArg, joinArg), "pinned");
|
|
4045
4437
|
}
|
|
4046
4438
|
);
|
|
4047
4439
|
}
|
|
@@ -4050,17 +4442,19 @@ const defaultPagedRuntime = new PagedRuntime();
|
|
|
4050
4442
|
function initializePagedApi(api3, workspace) {
|
|
4051
4443
|
defaultPagedRuntime.initialize(api3, workspace);
|
|
4052
4444
|
}
|
|
4053
|
-
function clearPagedApi() {
|
|
4054
|
-
defaultPagedRuntime.clear();
|
|
4445
|
+
function clearPagedApi(api3) {
|
|
4446
|
+
defaultPagedRuntime.clear(api3);
|
|
4055
4447
|
}
|
|
4056
4448
|
const PagedPlatform = [
|
|
4057
4449
|
defaultPagedRuntime.buildPlatform(null),
|
|
4450
|
+
defaultPagedRuntime.buildPinnedPlatform(null),
|
|
4058
4451
|
...defaultPagedRuntime.buildPrimitives()
|
|
4059
4452
|
];
|
|
4060
4453
|
function createScopedPagedPlatform(pages) {
|
|
4061
4454
|
const allowed = new Set(pages.map((p2) => datasetPathToString(p2)));
|
|
4062
4455
|
return [
|
|
4063
4456
|
defaultPagedRuntime.buildPlatform(allowed),
|
|
4457
|
+
defaultPagedRuntime.buildPinnedPlatform(allowed),
|
|
4064
4458
|
...defaultPagedRuntime.buildPrimitives()
|
|
4065
4459
|
];
|
|
4066
4460
|
}
|
|
@@ -4083,13 +4477,12 @@ function createDefaultFunctionApi(apiUrl, repo, getToken) {
|
|
|
4083
4477
|
async call(workspace, fn3, req) {
|
|
4084
4478
|
return workspaceFunctionCall(apiUrl, repo, workspace, fn3, {
|
|
4085
4479
|
args: req.args,
|
|
4086
|
-
runner:
|
|
4087
|
-
limits:
|
|
4480
|
+
runner: none$1,
|
|
4481
|
+
limits: none$1
|
|
4088
4482
|
}, opts());
|
|
4089
4483
|
}
|
|
4090
4484
|
};
|
|
4091
4485
|
}
|
|
4092
|
-
const eastTypeEqual$1 = equalFor(EastTypeType);
|
|
4093
4486
|
function signatureOfFuncHandleType(handleType) {
|
|
4094
4487
|
var _a2, _b2;
|
|
4095
4488
|
if (handleType.type !== "Struct") {
|
|
@@ -4106,11 +4499,11 @@ function signatureOfFuncHandleType(handleType) {
|
|
|
4106
4499
|
if (readOut.type !== "Variant") {
|
|
4107
4500
|
throw new Error("Func.bind: read() must return Option(Output)");
|
|
4108
4501
|
}
|
|
4109
|
-
const
|
|
4110
|
-
if (!
|
|
4502
|
+
const some22 = readOut.value.find((a2) => a2.name === "some");
|
|
4503
|
+
if (!some22) {
|
|
4111
4504
|
throw new Error("Func.bind: read() must return Option(Output)");
|
|
4112
4505
|
}
|
|
4113
|
-
return { inputs, output:
|
|
4506
|
+
return { inputs, output: some22.type };
|
|
4114
4507
|
}
|
|
4115
4508
|
function errorOfExecuteResult(result) {
|
|
4116
4509
|
const outcome = result.outcome;
|
|
@@ -4186,8 +4579,15 @@ class FuncRuntime extends TrackedChannelStore {
|
|
|
4186
4579
|
this.api = api3;
|
|
4187
4580
|
this.workspace = workspace;
|
|
4188
4581
|
}
|
|
4189
|
-
/**
|
|
4190
|
-
|
|
4582
|
+
/**
|
|
4583
|
+
* Tear down the adapter and all call state.
|
|
4584
|
+
*
|
|
4585
|
+
* @param api - Clear only while this is the installed adapter, so a
|
|
4586
|
+
* provider tearing down after another installed its own leaves that one
|
|
4587
|
+
* in place
|
|
4588
|
+
*/
|
|
4589
|
+
clear(api3) {
|
|
4590
|
+
if (api3 !== void 0 && this.api !== api3) return;
|
|
4191
4591
|
this.api = null;
|
|
4192
4592
|
this.workspace = null;
|
|
4193
4593
|
this.clearChannels();
|
|
@@ -4226,8 +4626,8 @@ class FuncRuntime extends TrackedChannelStore {
|
|
|
4226
4626
|
stderr: ""
|
|
4227
4627
|
};
|
|
4228
4628
|
}
|
|
4229
|
-
const inputsMatch = deployed.inputTypes.length === sig.inputs.length && deployed.inputTypes.every((t4, i) =>
|
|
4230
|
-
const outputMatches =
|
|
4629
|
+
const inputsMatch = deployed.inputTypes.length === sig.inputs.length && deployed.inputTypes.every((t4, i) => isTypeValueEqual(t4, sig.inputs[i]));
|
|
4630
|
+
const outputMatches = isTypeValueEqual(deployed.outputType, sig.output);
|
|
4231
4631
|
if (!inputsMatch || !outputMatches) {
|
|
4232
4632
|
const message = `signature mismatch for "${name}": bound (${sig.inputs.length} inputs) disagrees with the deployed package`;
|
|
4233
4633
|
return {
|
|
@@ -4330,7 +4730,7 @@ class FuncRuntime extends TrackedChannelStore {
|
|
|
4330
4730
|
FuncBindPrimitives.read.implement((_outputType) => (nameArg) => {
|
|
4331
4731
|
const { key, entry } = channel(nameArg);
|
|
4332
4732
|
runtime.track(key);
|
|
4333
|
-
return entry.result !== void 0 ?
|
|
4733
|
+
return entry.result !== void 0 ? some(entry.result) : none$1;
|
|
4334
4734
|
}),
|
|
4335
4735
|
FuncBindPrimitives.status.implement((nameArg) => {
|
|
4336
4736
|
const { key, entry } = channel(nameArg);
|
|
@@ -4340,7 +4740,7 @@ class FuncRuntime extends TrackedChannelStore {
|
|
|
4340
4740
|
FuncBindPrimitives.error.implement((nameArg) => {
|
|
4341
4741
|
const { key, entry } = channel(nameArg);
|
|
4342
4742
|
runtime.track(key);
|
|
4343
|
-
return entry.status === "failed" && entry.error !== void 0 ?
|
|
4743
|
+
return entry.status === "failed" && entry.error !== void 0 ? some(entry.error) : none$1;
|
|
4344
4744
|
}),
|
|
4345
4745
|
FuncBindPrimitives.pending.implement((nameArg) => {
|
|
4346
4746
|
const { key, entry } = channel(nameArg);
|
|
@@ -4420,8 +4820,8 @@ const defaultFuncRuntime = new FuncRuntime();
|
|
|
4420
4820
|
function initializeFunctionApi(api3, workspace) {
|
|
4421
4821
|
defaultFuncRuntime.initialize(api3, workspace);
|
|
4422
4822
|
}
|
|
4423
|
-
function clearFunctionApi() {
|
|
4424
|
-
defaultFuncRuntime.clear();
|
|
4823
|
+
function clearFunctionApi(api3) {
|
|
4824
|
+
defaultFuncRuntime.clear(api3);
|
|
4425
4825
|
}
|
|
4426
4826
|
const FuncPlatform = [
|
|
4427
4827
|
defaultFuncRuntime.buildPlatform(null),
|
|
@@ -8194,12 +8594,6 @@ function errorOfMutationResult(result) {
|
|
|
8194
8594
|
message: `reducer exited with code ${outcome.value.exitCode}`,
|
|
8195
8595
|
stderr: outcome.value.stderr
|
|
8196
8596
|
};
|
|
8197
|
-
case "too_large":
|
|
8198
|
-
return {
|
|
8199
|
-
kind: variant("too_large", { bytes: outcome.value.bytes, limit: outcome.value.limit }),
|
|
8200
|
-
message: `new state too large (${outcome.value.bytes} bytes, limit ${outcome.value.limit})`,
|
|
8201
|
-
stderr: outcome.value.stderr
|
|
8202
|
-
};
|
|
8203
8597
|
case "timed_out":
|
|
8204
8598
|
return {
|
|
8205
8599
|
kind: variant("timed_out", { ms: outcome.value.ms }),
|
|
@@ -8259,8 +8653,15 @@ class RecordRuntime extends TrackedChannelStore {
|
|
|
8259
8653
|
this.cache = cache3;
|
|
8260
8654
|
this.workspace = workspace;
|
|
8261
8655
|
}
|
|
8262
|
-
/**
|
|
8263
|
-
|
|
8656
|
+
/**
|
|
8657
|
+
* Tear down the adapter and all record state.
|
|
8658
|
+
*
|
|
8659
|
+
* @param api - Clear only while this is the installed adapter, so a
|
|
8660
|
+
* provider tearing down after another installed its own leaves that one
|
|
8661
|
+
* in place
|
|
8662
|
+
*/
|
|
8663
|
+
clear(api3) {
|
|
8664
|
+
if (api3 !== void 0 && this.api !== api3) return;
|
|
8264
8665
|
this.api = null;
|
|
8265
8666
|
this.cache = null;
|
|
8266
8667
|
this.workspace = null;
|
|
@@ -8568,8 +8969,8 @@ const defaultRecordRuntime = new RecordRuntime();
|
|
|
8568
8969
|
function initializeRecordApi(api3, cache3, workspace) {
|
|
8569
8970
|
defaultRecordRuntime.initialize(api3, cache3, workspace);
|
|
8570
8971
|
}
|
|
8571
|
-
function clearRecordApi() {
|
|
8572
|
-
defaultRecordRuntime.clear();
|
|
8972
|
+
function clearRecordApi(api3) {
|
|
8973
|
+
defaultRecordRuntime.clear(api3);
|
|
8573
8974
|
}
|
|
8574
8975
|
const RecordPlatform = [
|
|
8575
8976
|
defaultRecordRuntime.buildPlatform(null),
|
|
@@ -8595,7 +8996,8 @@ function createInMemoryRecordApi(cache3, workspace, defs2) {
|
|
|
8595
8996
|
state: `${def.name}-state-0`.padEnd(64, "0"),
|
|
8596
8997
|
mutation: "$init",
|
|
8597
8998
|
actor: "memory",
|
|
8598
|
-
at: /* @__PURE__ */ new Date(0)
|
|
8999
|
+
at: /* @__PURE__ */ new Date(0),
|
|
9000
|
+
delta: none$1
|
|
8599
9001
|
};
|
|
8600
9002
|
compiled.set(def.name, { stateType, mutations, commits: [genesis], seq: 0 });
|
|
8601
9003
|
void cache3.write(workspace, recordPath(def.name), encodeBeast2For(stateType)(def.initial));
|
|
@@ -8627,7 +9029,8 @@ function createInMemoryRecordApi(cache3, workspace, defs2) {
|
|
|
8627
9029
|
state: `${record}-state-${c2.seq}`.padEnd(64, "0"),
|
|
8628
9030
|
mutation,
|
|
8629
9031
|
actor: "memory",
|
|
8630
|
-
at: /* @__PURE__ */ new Date(0)
|
|
9032
|
+
at: /* @__PURE__ */ new Date(0),
|
|
9033
|
+
delta: none$1
|
|
8631
9034
|
});
|
|
8632
9035
|
return { outcome: variant("committed", { commitHash: hash2, stateHash: `${record}-state-${c2.seq}`.padEnd(64, "0") }) };
|
|
8633
9036
|
},
|
|
@@ -8676,68 +9079,49 @@ function ReactiveDatasetProvider({
|
|
|
8676
9079
|
children: children2
|
|
8677
9080
|
}) {
|
|
8678
9081
|
const e3 = useE3Config();
|
|
9082
|
+
const { apiUrl, workspace } = e3;
|
|
9083
|
+
const repo = e3.repo ?? "default";
|
|
8679
9084
|
const tokenRef = useRef(e3.token ?? null);
|
|
8680
9085
|
tokenRef.current = e3.token ?? null;
|
|
8681
|
-
const
|
|
8682
|
-
() => createDefaultDatasetApi(e3.apiUrl, e3.repo ?? "default", () => tokenRef.current),
|
|
8683
|
-
[e3.apiUrl, e3.repo]
|
|
8684
|
-
);
|
|
8685
|
-
const cache3 = useMemo(() => {
|
|
8686
|
-
const cfg = {};
|
|
8687
|
-
if (e3.workspace !== void 0) cfg.workspace = e3.workspace;
|
|
8688
|
-
return new ReactiveDatasetCache(cfg, api3);
|
|
8689
|
-
}, [api3, e3.workspace]);
|
|
8690
|
-
useMemo(() => {
|
|
8691
|
-
initializeReactiveDatasetCache(cache3);
|
|
8692
|
-
cache3.setScheduler((notify3) => queueMicrotask(notify3));
|
|
8693
|
-
}, [cache3]);
|
|
8694
|
-
useMemo(() => {
|
|
8695
|
-
if (e3.workspace !== void 0) {
|
|
8696
|
-
initializeFunctionApi(
|
|
8697
|
-
createDefaultFunctionApi(e3.apiUrl, e3.repo ?? "default", () => tokenRef.current),
|
|
8698
|
-
e3.workspace
|
|
8699
|
-
);
|
|
8700
|
-
}
|
|
8701
|
-
}, [e3.apiUrl, e3.repo, e3.workspace]);
|
|
8702
|
-
useMemo(() => {
|
|
8703
|
-
if (e3.workspace !== void 0) {
|
|
8704
|
-
initializePagedApi(
|
|
8705
|
-
createDefaultPagedApi(e3.apiUrl, e3.repo ?? "default", () => tokenRef.current),
|
|
8706
|
-
e3.workspace
|
|
8707
|
-
);
|
|
8708
|
-
}
|
|
8709
|
-
}, [e3.apiUrl, e3.repo, e3.workspace]);
|
|
8710
|
-
useMemo(() => {
|
|
8711
|
-
if (e3.workspace !== void 0) {
|
|
8712
|
-
initializeRecordApi(
|
|
8713
|
-
createDefaultRecordApi(e3.apiUrl, e3.repo ?? "default", () => tokenRef.current),
|
|
8714
|
-
cache3,
|
|
8715
|
-
e3.workspace
|
|
8716
|
-
);
|
|
8717
|
-
}
|
|
8718
|
-
}, [e3.apiUrl, e3.repo, e3.workspace, cache3]);
|
|
9086
|
+
const [installed, setInstalled] = useState(null);
|
|
8719
9087
|
useEffect(() => {
|
|
9088
|
+
const getToken = () => tokenRef.current;
|
|
9089
|
+
const cache22 = new ReactiveDatasetCache(
|
|
9090
|
+
workspace !== void 0 ? { workspace } : {},
|
|
9091
|
+
createDefaultDatasetApi(apiUrl, repo, getToken)
|
|
9092
|
+
);
|
|
9093
|
+
cache22.setScheduler((notify3) => queueMicrotask(notify3));
|
|
9094
|
+
initializeReactiveDatasetCache(cache22);
|
|
9095
|
+
const functionApi = createDefaultFunctionApi(apiUrl, repo, getToken);
|
|
9096
|
+
const pagedApi = createDefaultPagedApi(apiUrl, repo, getToken, cache22);
|
|
9097
|
+
const recordApi = createDefaultRecordApi(apiUrl, repo, getToken);
|
|
9098
|
+
if (workspace !== void 0) {
|
|
9099
|
+
initializeFunctionApi(functionApi, workspace);
|
|
9100
|
+
initializePagedApi(pagedApi, workspace);
|
|
9101
|
+
initializeRecordApi(recordApi, cache22, workspace);
|
|
9102
|
+
}
|
|
9103
|
+
const unscopeStaged = getStagedStore().setScope(JSON.stringify([apiUrl, repo]));
|
|
9104
|
+
setInstalled({ apiUrl, repo, workspace, cache: cache22 });
|
|
8720
9105
|
return () => {
|
|
8721
|
-
|
|
8722
|
-
|
|
8723
|
-
|
|
8724
|
-
|
|
8725
|
-
|
|
8726
|
-
|
|
8727
|
-
if (
|
|
9106
|
+
clearReactiveDatasetCache(cache22);
|
|
9107
|
+
clearFunctionApi(functionApi);
|
|
9108
|
+
clearPagedApi(pagedApi);
|
|
9109
|
+
clearRecordApi(recordApi);
|
|
9110
|
+
unscopeStaged();
|
|
9111
|
+
cache22.destroy();
|
|
9112
|
+
if (workspace) clearBindingRegistry(workspace);
|
|
8728
9113
|
else clearBindingRegistry();
|
|
8729
9114
|
};
|
|
8730
|
-
}, [
|
|
9115
|
+
}, [apiUrl, repo, workspace]);
|
|
9116
|
+
const cache3 = installed !== null && installed.apiUrl === apiUrl && installed.repo === repo && installed.workspace === workspace ? installed.cache : null;
|
|
8731
9117
|
useEffect(() => {
|
|
8732
|
-
if (typeof window
|
|
8733
|
-
|
|
8734
|
-
}
|
|
9118
|
+
if (cache3 === null || typeof window === "undefined") return;
|
|
9119
|
+
window.__EAST_REACTIVE_DATASET_CACHE__ = cache3;
|
|
8735
9120
|
return () => {
|
|
8736
|
-
|
|
8737
|
-
delete window.__EAST_REACTIVE_DATASET_CACHE__;
|
|
8738
|
-
}
|
|
9121
|
+
delete window.__EAST_REACTIVE_DATASET_CACHE__;
|
|
8739
9122
|
};
|
|
8740
9123
|
}, [cache3]);
|
|
9124
|
+
if (cache3 === null) return null;
|
|
8741
9125
|
return /* @__PURE__ */ jsx$1(ReactiveDatasetCacheContext.Provider, { value: cache3, children: children2 });
|
|
8742
9126
|
}
|
|
8743
9127
|
function useReactiveDatasetCache() {
|
|
@@ -8856,12 +9240,11 @@ function collectLeaves(node2, into = []) {
|
|
|
8856
9240
|
else for (const c2 of node2.children) collectLeaves(c2, into);
|
|
8857
9241
|
return into;
|
|
8858
9242
|
}
|
|
9243
|
+
const readString = parseFor(StringType);
|
|
8859
9244
|
function leafDisplayLabel(seg) {
|
|
8860
|
-
if (seg.kind === "key"
|
|
8861
|
-
|
|
8862
|
-
|
|
8863
|
-
} catch {
|
|
8864
|
-
}
|
|
9245
|
+
if (seg.kind === "key") {
|
|
9246
|
+
const read = readString(seg.key);
|
|
9247
|
+
if (read.success) return read.value;
|
|
8865
9248
|
}
|
|
8866
9249
|
return pathDisplay(seg);
|
|
8867
9250
|
}
|
|
@@ -8913,57 +9296,28 @@ function walkPatchToTree(typeValue, patch, rootLabel) {
|
|
|
8913
9296
|
return root2;
|
|
8914
9297
|
}
|
|
8915
9298
|
const MAX_INLINE_CHARS = 48;
|
|
8916
|
-
function formatLeafValue(
|
|
8917
|
-
if (
|
|
8918
|
-
|
|
8919
|
-
|
|
8920
|
-
case "Null":
|
|
8921
|
-
return "null";
|
|
8922
|
-
case "Boolean":
|
|
8923
|
-
return value ? "true" : "false";
|
|
8924
|
-
case "Integer":
|
|
8925
|
-
return typeof value === "bigint" ? value.toString() : String(value);
|
|
8926
|
-
case "Float":
|
|
8927
|
-
return formatFloat(value);
|
|
8928
|
-
case "String":
|
|
8929
|
-
return value === "" ? '""' : String(value);
|
|
8930
|
-
case "DateTime":
|
|
8931
|
-
return value instanceof Date ? value.toISOString() : String(value);
|
|
8932
|
-
case "Blob":
|
|
8933
|
-
return value instanceof Uint8Array ? `${value.length} bytes` : truncate(printFor(typeValue)(value));
|
|
8934
|
-
case "Variant":
|
|
8935
|
-
if (isVariant(value)) {
|
|
8936
|
-
const cases = typeValue.value;
|
|
8937
|
-
const sub = cases.find((c2) => c2.name === value.type);
|
|
8938
|
-
if (value.value === null || value.value === void 0 || !sub) return value.type;
|
|
8939
|
-
return `${value.type}(${truncate(printFor(sub.type)(value.value))})`;
|
|
8940
|
-
}
|
|
8941
|
-
return "<value>";
|
|
8942
|
-
default:
|
|
8943
|
-
return truncate(printFor(typeValue)(value));
|
|
8944
|
-
}
|
|
8945
|
-
}
|
|
8946
|
-
function formatFloat(v3) {
|
|
8947
|
-
if (typeof v3 !== "number") return String(v3);
|
|
8948
|
-
if (Number.isInteger(v3)) return v3.toFixed(1);
|
|
8949
|
-
return Math.abs(v3) >= 1e3 ? v3.toLocaleString("en-US", { maximumFractionDigits: 2 }) : String(Number(v3.toFixed(4)));
|
|
9299
|
+
function formatLeafValue(leafType, value, words = formatters()) {
|
|
9300
|
+
if (leafType.type === "Float") return words.float(value);
|
|
9301
|
+
const text = printFor(leafType)(value);
|
|
9302
|
+
return leafType.type === "String" ? text : truncate(text);
|
|
8950
9303
|
}
|
|
8951
9304
|
function truncate(s2) {
|
|
8952
9305
|
return s2.length > MAX_INLINE_CHARS ? s2.slice(0, MAX_INLINE_CHARS - 1) + "…" : s2;
|
|
8953
9306
|
}
|
|
8954
|
-
function formatBindingLabel(
|
|
8955
|
-
|
|
8956
|
-
|
|
8957
|
-
|
|
8958
|
-
|
|
8959
|
-
|
|
8960
|
-
if (last2.type === "key") return String(last2.value);
|
|
9307
|
+
function formatBindingLabel(path2) {
|
|
9308
|
+
const last2 = path2[path2.length - 1];
|
|
9309
|
+
if (last2 === void 0) return "(root)";
|
|
9310
|
+
switch (last2.type) {
|
|
9311
|
+
case "field":
|
|
9312
|
+
return last2.value;
|
|
8961
9313
|
}
|
|
8962
|
-
return String(last2);
|
|
8963
9314
|
}
|
|
8964
|
-
|
|
8965
|
-
|
|
8966
|
-
|
|
9315
|
+
const DATETIME_LOCAL = tokenizeDateTimeFormat("YYYY-MM-DDTHH:mm");
|
|
9316
|
+
const readBoolean = parseFor(BooleanType);
|
|
9317
|
+
const readInteger = parseFor(IntegerType);
|
|
9318
|
+
const readFloat = parseFor(FloatType);
|
|
9319
|
+
function isPrimitiveLeafType(leafType) {
|
|
9320
|
+
switch (leafType.type) {
|
|
8967
9321
|
case "Boolean":
|
|
8968
9322
|
case "Integer":
|
|
8969
9323
|
case "Float":
|
|
@@ -8975,49 +9329,46 @@ function isPrimitiveLeafType(t4) {
|
|
|
8975
9329
|
}
|
|
8976
9330
|
}
|
|
8977
9331
|
function formatManualDraft(leafType, value) {
|
|
8978
|
-
if (
|
|
9332
|
+
if (value === void 0) return "";
|
|
8979
9333
|
switch (leafType.type) {
|
|
8980
9334
|
case "Boolean":
|
|
8981
|
-
return value ? "true" : "false";
|
|
8982
9335
|
case "Integer":
|
|
8983
|
-
return typeof value === "bigint" ? value.toString() : String(value);
|
|
8984
9336
|
case "Float":
|
|
8985
|
-
return
|
|
9337
|
+
return printFor(leafType)(value);
|
|
8986
9338
|
case "String":
|
|
8987
|
-
return
|
|
8988
|
-
case "DateTime":
|
|
8989
|
-
|
|
8990
|
-
return value.toISOString().slice(0, 16);
|
|
8991
|
-
}
|
|
9339
|
+
return value;
|
|
9340
|
+
case "DateTime":
|
|
9341
|
+
return formatDateTime(value, DATETIME_LOCAL);
|
|
8992
9342
|
default:
|
|
8993
9343
|
return "";
|
|
8994
9344
|
}
|
|
8995
9345
|
}
|
|
8996
9346
|
function parseManualDraft(leafType, draft) {
|
|
8997
|
-
|
|
8998
|
-
|
|
8999
|
-
|
|
9000
|
-
|
|
9001
|
-
case "Float": {
|
|
9002
|
-
const n2 = Number(draft);
|
|
9003
|
-
if (Number.isNaN(n2)) return { ok: false };
|
|
9004
|
-
return { ok: true, value: n2 };
|
|
9005
|
-
}
|
|
9006
|
-
case "String":
|
|
9007
|
-
return { ok: true, value: draft };
|
|
9008
|
-
case "DateTime": {
|
|
9009
|
-
const d2 = new Date(draft);
|
|
9010
|
-
if (Number.isNaN(d2.getTime())) return { ok: false };
|
|
9011
|
-
return { ok: true, value: d2 };
|
|
9012
|
-
}
|
|
9013
|
-
default:
|
|
9014
|
-
return { ok: false };
|
|
9347
|
+
switch (leafType.type) {
|
|
9348
|
+
case "Boolean": {
|
|
9349
|
+
const read = readBoolean(draft);
|
|
9350
|
+
return read.success ? { ok: true, value: read.value } : { ok: false };
|
|
9015
9351
|
}
|
|
9016
|
-
|
|
9017
|
-
|
|
9352
|
+
case "Integer": {
|
|
9353
|
+
const read = readInteger(draft);
|
|
9354
|
+
return read.success ? { ok: true, value: read.value } : { ok: false };
|
|
9355
|
+
}
|
|
9356
|
+
case "Float": {
|
|
9357
|
+
const read = readFloat(draft);
|
|
9358
|
+
return read.success ? { ok: true, value: read.value } : { ok: false };
|
|
9359
|
+
}
|
|
9360
|
+
case "String":
|
|
9361
|
+
return { ok: true, value: draft };
|
|
9362
|
+
case "DateTime": {
|
|
9363
|
+
const read = parseDateTimeFormatted(draft, DATETIME_LOCAL);
|
|
9364
|
+
return read.success ? { ok: true, value: read.value } : { ok: false };
|
|
9365
|
+
}
|
|
9366
|
+
default:
|
|
9367
|
+
return { ok: false };
|
|
9018
9368
|
}
|
|
9019
9369
|
}
|
|
9020
|
-
const diffValueEqual =
|
|
9370
|
+
const diffValueEqual = equivalentFor(Diff.Component.schema);
|
|
9371
|
+
const diffValueDataEqual = equalFor(Diff.Component.schema);
|
|
9021
9372
|
function getOpt$1(opt) {
|
|
9022
9373
|
return opt.type === "some" ? opt.value : void 0;
|
|
9023
9374
|
}
|
|
@@ -9243,6 +9594,7 @@ function ActionBtn({
|
|
|
9243
9594
|
);
|
|
9244
9595
|
}
|
|
9245
9596
|
const DiffRow = memo(function DiffRow2({ row, depth, bindingPathStr, showActions, onDiscard, annotation, metrics }) {
|
|
9597
|
+
const words = useFormatters();
|
|
9246
9598
|
const handleDiscard = useCallback(() => onDiscard(bindingPathStr, row.path), [onDiscard, bindingPathStr, row.path]);
|
|
9247
9599
|
return /* @__PURE__ */ jsxs(
|
|
9248
9600
|
Box,
|
|
@@ -9275,7 +9627,7 @@ const DiffRow = memo(function DiffRow2({ row, depth, bindingPathStr, showActions
|
|
|
9275
9627
|
row.stale && /* @__PURE__ */ jsxs(Text, { fontSize: "11px", color: "fg.warning", fontWeight: 500, children: [
|
|
9276
9628
|
/* @__PURE__ */ jsx$1(FontAwesomeIcon, { icon: faTriangleExclamation }),
|
|
9277
9629
|
" ",
|
|
9278
|
-
row.stale.actual === void 0 ? "stale — source no longer has this entry" : `stale — source actually has ${formatLeafValue(row.leafType, row.stale.actual)}`
|
|
9630
|
+
row.stale.actual === void 0 ? "stale — source no longer has this entry" : `stale — source actually has ${formatLeafValue(row.leafType, row.stale.actual, words)}`
|
|
9279
9631
|
] }),
|
|
9280
9632
|
annotation && /* @__PURE__ */ jsx$1(Text, { fontSize: "11px", color: `${annotation.tone}.700`, fontWeight: 500, children: annotation.text })
|
|
9281
9633
|
] }),
|
|
@@ -9284,13 +9636,13 @@ const DiffRow = memo(function DiffRow2({ row, depth, bindingPathStr, showActions
|
|
|
9284
9636
|
row.before !== void 0 && /* @__PURE__ */ jsxs(Chip$1, { fontSize: metrics.chipFontSize, children: [
|
|
9285
9637
|
/* @__PURE__ */ jsx$1(Box, { as: "span", color: "fg.danger", children: /* @__PURE__ */ jsx$1(FontAwesomeIcon, { icon: faMinus }) }),
|
|
9286
9638
|
" ",
|
|
9287
|
-
formatLeafValue(row.leafType, row.before)
|
|
9639
|
+
formatLeafValue(row.leafType, row.before, words)
|
|
9288
9640
|
] }),
|
|
9289
9641
|
row.before !== void 0 && row.after !== void 0 && /* @__PURE__ */ jsx$1(Box, { as: "span", color: "fg.subtle", fontSize: "11px", children: /* @__PURE__ */ jsx$1(FontAwesomeIcon, { icon: faArrowRight }) }),
|
|
9290
9642
|
row.after !== void 0 && /* @__PURE__ */ jsxs(Chip$1, { fontSize: metrics.chipFontSize, children: [
|
|
9291
9643
|
/* @__PURE__ */ jsx$1(Box, { as: "span", color: "fg.success", children: /* @__PURE__ */ jsx$1(FontAwesomeIcon, { icon: faPlus }) }),
|
|
9292
9644
|
" ",
|
|
9293
|
-
formatLeafValue(row.leafType, row.after)
|
|
9645
|
+
formatLeafValue(row.leafType, row.after, words)
|
|
9294
9646
|
] })
|
|
9295
9647
|
] }),
|
|
9296
9648
|
showActions && /* @__PURE__ */ jsx$1(ActionBtn, { icon: faXmark, title: "Discard this change", onClick: handleDiscard, size: metrics.actionBtnSize })
|
|
@@ -9299,9 +9651,11 @@ const DiffRow = memo(function DiffRow2({ row, depth, bindingPathStr, showActions
|
|
|
9299
9651
|
}
|
|
9300
9652
|
);
|
|
9301
9653
|
});
|
|
9654
|
+
const REMOVED = "(removed)";
|
|
9302
9655
|
const ConflictRow = memo(function ConflictRow2({ row, depth, bindingPathStr, serverValue, resolution, onResolve, metrics }) {
|
|
9303
|
-
const
|
|
9304
|
-
const
|
|
9656
|
+
const words = useFormatters();
|
|
9657
|
+
const yoursStr = row.after === void 0 ? REMOVED : formatLeafValue(row.leafType, row.after, words);
|
|
9658
|
+
const theirsStr = serverValue === void 0 ? REMOVED : formatLeafValue(row.leafType, serverValue, words);
|
|
9305
9659
|
const isYours = (resolution == null ? void 0 : resolution.type) === "keepA";
|
|
9306
9660
|
const isTheirs = (resolution == null ? void 0 : resolution.type) === "keepB";
|
|
9307
9661
|
const isManual = (resolution == null ? void 0 : resolution.type) === "manual";
|
|
@@ -9367,7 +9721,7 @@ const ConflictRow = memo(function ConflictRow2({ row, depth, bindingPathStr, ser
|
|
|
9367
9721
|
{
|
|
9368
9722
|
selected: isManual,
|
|
9369
9723
|
leafType: row.leafType,
|
|
9370
|
-
value:
|
|
9724
|
+
value: (resolution == null ? void 0 : resolution.type) === "manual" ? resolution.value : row.after,
|
|
9371
9725
|
onChange: handleManual
|
|
9372
9726
|
}
|
|
9373
9727
|
)
|
|
@@ -9484,9 +9838,8 @@ function ManualEditor({
|
|
|
9484
9838
|
const fire = useCallback((parsed) => {
|
|
9485
9839
|
queueMicrotask(() => onChange2(parsed));
|
|
9486
9840
|
}, [onChange2]);
|
|
9487
|
-
if (!leafType) return null;
|
|
9488
9841
|
if (leafType.type === "Boolean") {
|
|
9489
|
-
const checked =
|
|
9842
|
+
const checked = value === true;
|
|
9490
9843
|
return /* @__PURE__ */ jsxs(
|
|
9491
9844
|
Box,
|
|
9492
9845
|
{
|
|
@@ -9668,9 +10021,10 @@ const EastChakraDiff = memo(function EastChakraDiff2({ value }) {
|
|
|
9668
10021
|
const [conflicts, setConflicts] = useState(null);
|
|
9669
10022
|
const [resolutions, setResolutions] = useState(/* @__PURE__ */ new Map());
|
|
9670
10023
|
const [committing, setCommitting] = useState(false);
|
|
10024
|
+
const data4 = useDataStable(value, diffValueDataEqual);
|
|
9671
10025
|
const irBindings = useMemo(
|
|
9672
|
-
() =>
|
|
9673
|
-
[
|
|
10026
|
+
() => data4.bindings ?? [],
|
|
10027
|
+
[data4.bindings]
|
|
9674
10028
|
);
|
|
9675
10029
|
const interactive = !(getOpt$1(value.readonly) ?? false);
|
|
9676
10030
|
const onCommittedFn = getOpt$1(value.onCommitted);
|
|
@@ -9704,7 +10058,7 @@ const EastChakraDiff = memo(function EastChakraDiff2({ value }) {
|
|
|
9704
10058
|
useEffect(() => {
|
|
9705
10059
|
setConflicts(null);
|
|
9706
10060
|
setResolutions(/* @__PURE__ */ new Map());
|
|
9707
|
-
}, [
|
|
10061
|
+
}, [data4, stagedVersion, datasetVersion]);
|
|
9708
10062
|
const visibleBindings = useMemo(
|
|
9709
10063
|
() => bindings.filter((b2) => b2.leaves.length > 0),
|
|
9710
10064
|
[bindings]
|
|
@@ -23083,13 +23437,13 @@ var hashIterableInts = function hashIterableInts2(iterator) {
|
|
|
23083
23437
|
}
|
|
23084
23438
|
return hash2;
|
|
23085
23439
|
};
|
|
23086
|
-
var hashInt = function hashInt2(
|
|
23440
|
+
var hashInt = function hashInt2(num) {
|
|
23087
23441
|
var seed = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : DEFAULT_HASH_SEED;
|
|
23088
|
-
return seed * K +
|
|
23442
|
+
return seed * K + num | 0;
|
|
23089
23443
|
};
|
|
23090
|
-
var hashIntAlt = function hashIntAlt2(
|
|
23444
|
+
var hashIntAlt = function hashIntAlt2(num) {
|
|
23091
23445
|
var seed = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : DEFAULT_HASH_SEED_ALT;
|
|
23092
|
-
return (seed << 5) + seed +
|
|
23446
|
+
return (seed << 5) + seed + num | 0;
|
|
23093
23447
|
};
|
|
23094
23448
|
var combineHashes = function combineHashes2(hash1, hash2) {
|
|
23095
23449
|
return hash1 * 2097152 + hash2;
|
|
@@ -23119,7 +23473,7 @@ var hashIntsArray = function hashIntsArray2(ints, seed) {
|
|
|
23119
23473
|
};
|
|
23120
23474
|
return hashIterableInts(iterator, seed);
|
|
23121
23475
|
};
|
|
23122
|
-
var hashString
|
|
23476
|
+
var hashString = function hashString2(str, seed) {
|
|
23123
23477
|
var entry = {
|
|
23124
23478
|
value: 0,
|
|
23125
23479
|
done: false
|
|
@@ -23146,9 +23500,9 @@ var hashStringsArray = function hashStringsArray2(strs) {
|
|
|
23146
23500
|
for (var i = 0; i < strs.length; i++) {
|
|
23147
23501
|
var str = strs[i];
|
|
23148
23502
|
if (i === 0) {
|
|
23149
|
-
hash2 = hashString
|
|
23503
|
+
hash2 = hashString(str);
|
|
23150
23504
|
} else {
|
|
23151
|
-
hash2 = hashString
|
|
23505
|
+
hash2 = hashString(str, hash2);
|
|
23152
23506
|
}
|
|
23153
23507
|
}
|
|
23154
23508
|
return hash2;
|
|
@@ -28714,9 +29068,9 @@ function requireGet() {
|
|
|
28714
29068
|
if (hasRequiredGet) return get_1;
|
|
28715
29069
|
hasRequiredGet = 1;
|
|
28716
29070
|
var baseGet = require_baseGet();
|
|
28717
|
-
function get3(object3, path2,
|
|
29071
|
+
function get3(object3, path2, defaultValue2) {
|
|
28718
29072
|
var result = object3 == null ? void 0 : baseGet(object3, path2);
|
|
28719
|
-
return result === void 0 ?
|
|
29073
|
+
return result === void 0 ? defaultValue2 : result;
|
|
28720
29074
|
}
|
|
28721
29075
|
get_1 = get3;
|
|
28722
29076
|
return get_1;
|
|
@@ -30286,7 +30640,7 @@ var cache = function cache2(fn3, name) {
|
|
|
30286
30640
|
var _p = eles[0]._private;
|
|
30287
30641
|
var tch = _p.traversalCache = _p.traversalCache || {};
|
|
30288
30642
|
var ch = tch[name] = tch[name] || [];
|
|
30289
|
-
var hash2 = hashString
|
|
30643
|
+
var hash2 = hashString(key);
|
|
30290
30644
|
var cacheHit = ch[hash2];
|
|
30291
30645
|
if (cacheHit) {
|
|
30292
30646
|
return cacheHit;
|
|
@@ -32892,13 +33246,13 @@ function styleCache(key, fn3, ele) {
|
|
|
32892
33246
|
}
|
|
32893
33247
|
}
|
|
32894
33248
|
function cacheStyleFunction(key, fn3) {
|
|
32895
|
-
key = hashString
|
|
33249
|
+
key = hashString(key);
|
|
32896
33250
|
return function cachedStyleFunction(ele) {
|
|
32897
33251
|
return styleCache(key, fn3, ele);
|
|
32898
33252
|
};
|
|
32899
33253
|
}
|
|
32900
33254
|
function cachePrototypeStyleFunction(key, fn3) {
|
|
32901
|
-
key = hashString
|
|
33255
|
+
key = hashString(key);
|
|
32902
33256
|
var selfFn = function selfFn2(ele) {
|
|
32903
33257
|
return fn3.call(ele);
|
|
32904
33258
|
};
|
|
@@ -43169,7 +43523,7 @@ BRp$9.applyLabelDimensions = function(ele) {
|
|
|
43169
43523
|
BRp$9.applyPrefixedLabelDimensions = function(ele, prefix2) {
|
|
43170
43524
|
var _p = ele._private;
|
|
43171
43525
|
var text = this.getLabelText(ele, prefix2);
|
|
43172
|
-
var cacheKey = hashString
|
|
43526
|
+
var cacheKey = hashString(text, ele._private.labelDimsKey);
|
|
43173
43527
|
if (getPrefixedProperty(_p.rscratch, "prefixedLabelDimsKey", prefix2) === cacheKey) {
|
|
43174
43528
|
return;
|
|
43175
43529
|
}
|
|
@@ -47565,7 +47919,7 @@ CRp$9.drawArrowShape = function(edge, context, fill, edgeWidth, shape, shapeWidt
|
|
|
47565
47919
|
var shapeImpl = r2.arrowShapes[shape];
|
|
47566
47920
|
if (usePaths) {
|
|
47567
47921
|
var cache3 = r2.arrowPathCache = r2.arrowPathCache || [];
|
|
47568
|
-
var key = hashString
|
|
47922
|
+
var key = hashString(shape);
|
|
47569
47923
|
var cachedPath = cache3[key];
|
|
47570
47924
|
if (cachedPath != null) {
|
|
47571
47925
|
path2 = context = cachedPath;
|
|
@@ -54578,25 +54932,25 @@ function requireLayoutBase() {
|
|
|
54578
54932
|
}
|
|
54579
54933
|
}
|
|
54580
54934
|
};
|
|
54581
|
-
Layout2.transform = function(sliderValue,
|
|
54935
|
+
Layout2.transform = function(sliderValue, defaultValue2, minDiv, maxMul) {
|
|
54582
54936
|
if (minDiv != void 0 && maxMul != void 0) {
|
|
54583
|
-
var value =
|
|
54937
|
+
var value = defaultValue2;
|
|
54584
54938
|
if (sliderValue <= 50) {
|
|
54585
|
-
var minValue =
|
|
54586
|
-
value -= (
|
|
54939
|
+
var minValue = defaultValue2 / minDiv;
|
|
54940
|
+
value -= (defaultValue2 - minValue) / 50 * (50 - sliderValue);
|
|
54587
54941
|
} else {
|
|
54588
|
-
var maxValue =
|
|
54589
|
-
value += (maxValue -
|
|
54942
|
+
var maxValue = defaultValue2 * maxMul;
|
|
54943
|
+
value += (maxValue - defaultValue2) / 50 * (sliderValue - 50);
|
|
54590
54944
|
}
|
|
54591
54945
|
return value;
|
|
54592
54946
|
} else {
|
|
54593
54947
|
var a2, b2;
|
|
54594
54948
|
if (sliderValue <= 50) {
|
|
54595
|
-
a2 = 9 *
|
|
54596
|
-
b2 =
|
|
54949
|
+
a2 = 9 * defaultValue2 / 500;
|
|
54950
|
+
b2 = defaultValue2 / 10;
|
|
54597
54951
|
} else {
|
|
54598
|
-
a2 = 9 *
|
|
54599
|
-
b2 = -8 *
|
|
54952
|
+
a2 = 9 * defaultValue2 / 50;
|
|
54953
|
+
b2 = -8 * defaultValue2;
|
|
54600
54954
|
}
|
|
54601
54955
|
return a2 * sliderValue + b2;
|
|
54602
54956
|
}
|
|
@@ -57947,7 +58301,7 @@ function useBindingValue(binding) {
|
|
|
57947
58301
|
try {
|
|
57948
58302
|
return { value: handle.read(), pending: handle.pending(), error: void 0 };
|
|
57949
58303
|
} catch (e3) {
|
|
57950
|
-
console.error(`[Experiment] failed to read binding "${
|
|
58304
|
+
console.error(`[Experiment] failed to read binding "${pathToString$1(sourcePath)}":`, e3);
|
|
57951
58305
|
return { value: null, pending: false, error: e3 };
|
|
57952
58306
|
}
|
|
57953
58307
|
}, [handle, version2]);
|
|
@@ -57963,20 +58317,25 @@ function useBindingValue(binding) {
|
|
|
57963
58317
|
}, [handle]);
|
|
57964
58318
|
return { value, mode, pending, error: error3, mutate, commit, discard };
|
|
57965
58319
|
}
|
|
58320
|
+
function sameType(a2, b2) {
|
|
58321
|
+
return isTypeValueEqual(toEastTypeValue(a2), toEastTypeValue(b2));
|
|
58322
|
+
}
|
|
58323
|
+
function sameSignature(a2, b2) {
|
|
58324
|
+
const ai = a2.inputs;
|
|
58325
|
+
const bi = b2.inputs;
|
|
58326
|
+
return sameType(a2.output, b2.output) && (ai === null || bi === null ? ai === bi : ai.length === bi.length && ai.every((t4, i) => sameType(t4, bi[i])));
|
|
58327
|
+
}
|
|
57966
58328
|
const IDLE = { call: () => {
|
|
57967
58329
|
}, result: null, status: "idle", pending: false, error: null };
|
|
57968
58330
|
function useFuncCall(name, inputs, output2) {
|
|
57969
58331
|
const workspace = getReactiveDatasetCache().getConfig().workspace ?? "";
|
|
57970
58332
|
const ready4 = !!name && !!inputs && workspace !== "";
|
|
57971
|
-
const
|
|
57972
|
-
() => ready4 ? JSON.stringify([inputs.map((t4) => toEastTypeValue(t4)), toEastTypeValue(output2)]) : "",
|
|
57973
|
-
[ready4, inputs, output2]
|
|
57974
|
-
);
|
|
58333
|
+
const signature = useDataStable({ inputs, output: output2 }, sameSignature);
|
|
57975
58334
|
const handle = useMemo(() => {
|
|
57976
|
-
if (!ready4) return null;
|
|
57977
|
-
const handleType = toEastTypeValue(FuncBindHandleType(inputs,
|
|
58335
|
+
if (!ready4 || signature.inputs === null) return null;
|
|
58336
|
+
const handleType = toEastTypeValue(FuncBindHandleType(signature.inputs, signature.output));
|
|
57978
58337
|
return defaultFuncRuntime.buildHandle(handleType, name);
|
|
57979
|
-
}, [ready4, name, workspace,
|
|
58338
|
+
}, [ready4, name, workspace, signature]);
|
|
57980
58339
|
const channelKey = ready4 ? funcChannelKey(workspace, name) : "";
|
|
57981
58340
|
const version2 = useSyncExternalStore(
|
|
57982
58341
|
useCallback(
|
|
@@ -57987,7 +58346,6 @@ function useFuncCall(name, inputs, output2) {
|
|
|
57987
58346
|
useCallback(() => channelKey ? defaultFuncRuntime.getKeyVersion(channelKey) : 0, [channelKey])
|
|
57988
58347
|
);
|
|
57989
58348
|
return useMemo(() => {
|
|
57990
|
-
var _a2;
|
|
57991
58349
|
if (!handle) return IDLE;
|
|
57992
58350
|
let result = null;
|
|
57993
58351
|
let status = "idle";
|
|
@@ -57999,10 +58357,7 @@ function useFuncCall(name, inputs, output2) {
|
|
|
57999
58357
|
status = handle.status().type;
|
|
58000
58358
|
pending = handle.pending();
|
|
58001
58359
|
const err = handle.error();
|
|
58002
|
-
if (err.type === "some")
|
|
58003
|
-
const v3 = err.value;
|
|
58004
|
-
error3 = { kind: ((_a2 = v3.kind) == null ? void 0 : _a2.type) ?? "failed", message: v3.message ?? "", stdout: v3.stdout ?? "", stderr: v3.stderr ?? "" };
|
|
58005
|
-
}
|
|
58360
|
+
if (err.type === "some") error3 = err.value;
|
|
58006
58361
|
} catch {
|
|
58007
58362
|
}
|
|
58008
58363
|
return { call: (...args) => {
|
|
@@ -60620,207 +60975,14 @@ function GuidanceToggle({ on: on3, onToggle }) {
|
|
|
60620
60975
|
}
|
|
60621
60976
|
) });
|
|
60622
60977
|
}
|
|
60623
|
-
function ChartLabel({ x: x2, y: y2, w: w2, align, size: size3, weight: weight8, color: color2, family, help, children: children2 }) {
|
|
60624
|
-
const span = /* @__PURE__ */ jsx$1("span", { style: { fontSize: `${size3}px`, fontFamily: family, fontWeight: weight8, color: color2, lineHeight: 1, whiteSpace: "nowrap" }, children: children2 });
|
|
60625
|
-
return /* @__PURE__ */ jsx$1("foreignObject", { x: x2, y: y2, width: w2, height: size3 + 6, style: { overflow: "visible" }, children: /* @__PURE__ */ jsx$1("div", { style: { textAlign: align, fontSize: `${size3}px`, lineHeight: 1 }, children: help ? /* @__PURE__ */ jsx$1(Help, { id: help, children: span }) : span }) });
|
|
60626
|
-
}
|
|
60627
|
-
function svgText(size3, fill, family, weight8) {
|
|
60628
|
-
return { fontSize: `${size3}px`, fill, fontFamily: family, ...weight8 !== void 0 ? { fontWeight: weight8 } : {} };
|
|
60629
|
-
}
|
|
60630
|
-
function useMeasuredWidth() {
|
|
60631
|
-
const ref = useRef(null);
|
|
60632
|
-
const [w2, setW] = useState(0);
|
|
60633
|
-
useLayoutEffect(() => {
|
|
60634
|
-
const el = ref.current;
|
|
60635
|
-
if (!el) return;
|
|
60636
|
-
const update2 = () => setW(el.clientWidth);
|
|
60637
|
-
update2();
|
|
60638
|
-
const ro = new ResizeObserver(update2);
|
|
60639
|
-
ro.observe(el);
|
|
60640
|
-
return () => ro.disconnect();
|
|
60641
|
-
}, []);
|
|
60642
|
-
return [ref, w2];
|
|
60643
|
-
}
|
|
60644
|
-
function useChartTheme() {
|
|
60645
|
-
const system = useChakraContext();
|
|
60646
|
-
const tok = (k2, fallback) => system.token(k2, fallback);
|
|
60647
|
-
const tones = {
|
|
60648
|
-
neg: tok("colors.fg.danger", "#b85a4a"),
|
|
60649
|
-
pos: tok("colors.fg.success", "#2f7a5b"),
|
|
60650
|
-
warn: tok("colors.fg.warning", "#b8862d"),
|
|
60651
|
-
muted: tok("colors.fg.muted", "#6b8080"),
|
|
60652
|
-
brand: tok("colors.brand.solid", "#3a7780")
|
|
60653
|
-
};
|
|
60654
|
-
return {
|
|
60655
|
-
mono: tok("fonts.mono", '"JetBrains Mono", ui-monospace, monospace'),
|
|
60656
|
-
body: tok("fonts.body", "system-ui, -apple-system, sans-serif"),
|
|
60657
|
-
ink: tok("colors.fg", "#111b22"),
|
|
60658
|
-
muted: tones.muted,
|
|
60659
|
-
faint: tok("colors.fg.subtle", "#9bb0b0"),
|
|
60660
|
-
rule: tok("colors.border.subtle", "#e2e8e8"),
|
|
60661
|
-
ruleStrong: tok("colors.border.strong", "#cbd5d5"),
|
|
60662
|
-
surface: tok("colors.bg.surface", "#ffffff"),
|
|
60663
|
-
tone: (t4) => tones[t4] ?? tones.brand,
|
|
60664
|
-
labelSize: 10,
|
|
60665
|
-
titleSize: 11,
|
|
60666
|
-
lineWidth: 1.8,
|
|
60667
|
-
barWidth: 2.5,
|
|
60668
|
-
dotRadius: 2.6,
|
|
60669
|
-
scatterRadius: 3.4,
|
|
60670
|
-
areaOpacity: 0.16
|
|
60671
|
-
};
|
|
60672
|
-
}
|
|
60673
|
-
const fmt$2 = (n2) => Number.isInteger(n2) ? String(n2) : n2.toFixed(1);
|
|
60674
|
-
const signed$1 = (n2) => (n2 > 0 ? "+" : "") + fmt$2(n2);
|
|
60675
|
-
const niceCeil = (v3) => {
|
|
60676
|
-
if (v3 <= 1e-9) return 0;
|
|
60677
|
-
const mag = Math.pow(10, Math.floor(Math.log10(v3)));
|
|
60678
|
-
const n2 = v3 / mag;
|
|
60679
|
-
const step3 = n2 <= 1 ? 1 : n2 <= 1.5 ? 1.5 : n2 <= 2 ? 2 : n2 <= 3 ? 3 : n2 <= 4 ? 4 : n2 <= 5 ? 5 : n2 <= 6 ? 6 : n2 <= 8 ? 8 : 10;
|
|
60680
|
-
return step3 * mag;
|
|
60681
|
-
};
|
|
60682
|
-
function ForestPlot({ rows, min: min4, max: max5, unit: unit2, height: height2, rowHelp }) {
|
|
60683
|
-
const t4 = useChartTheme();
|
|
60684
|
-
const [ref, w2] = useMeasuredWidth();
|
|
60685
|
-
const n2 = rows.length;
|
|
60686
|
-
const hPx = height2 ?? 26 + n2 * 38;
|
|
60687
|
-
const padL = 124, padR = 46, padT = 20, padB = 30;
|
|
60688
|
-
const innerW = Math.max(0, w2 - padL - padR);
|
|
60689
|
-
const innerH = hPx - padT - padB;
|
|
60690
|
-
const x2 = createLinearScale({ domain: [min4, max5], range: [0, innerW] });
|
|
60691
|
-
const rowH = innerH / Math.max(1, n2);
|
|
60692
|
-
const zeroX = Math.max(0, Math.min(innerW, x2(0)));
|
|
60693
|
-
const frac = (v3) => max5 > min4 ? (v3 - min4) / (max5 - min4) : 0.5;
|
|
60694
|
-
const anchorAt = (v3) => frac(v3) < 0.06 ? "start" : frac(v3) > 0.94 ? "end" : "middle";
|
|
60695
|
-
const zf = frac(0);
|
|
60696
|
-
const ticks2 = zf > 0.12 && zf < 0.88 ? [min4, 0, max5] : [min4, max5];
|
|
60697
|
-
return /* @__PURE__ */ jsx$1(Box, { ref, width: "100%", height: `${hPx}px`, children: w2 > 0 && /* @__PURE__ */ jsx$1("svg", { width: w2, height: hPx, style: { display: "block" }, children: /* @__PURE__ */ jsxs(Group, { left: padL, top: padT, children: [
|
|
60698
|
-
/* @__PURE__ */ jsx$1(Line, { from: { x: zeroX, y: -4 }, to: { x: zeroX, y: innerH }, stroke: t4.muted, strokeWidth: 1, strokeDasharray: "3 2" }),
|
|
60699
|
-
/* @__PURE__ */ jsx$1("text", { x: zeroX, y: -6, textAnchor: anchorAt(0), style: svgText(t4.labelSize, t4.muted, t4.mono), children: "no effect" }),
|
|
60700
|
-
rows.map((r2, i) => {
|
|
60701
|
-
const cy = rowH * i + rowH / 2;
|
|
60702
|
-
const col = t4.tone(r2.tone);
|
|
60703
|
-
return /* @__PURE__ */ jsxs(Group, { top: cy, children: [
|
|
60704
|
-
/* @__PURE__ */ jsx$1(Line, { from: { x: x2(r2.lo), y: 0 }, to: { x: x2(r2.hi), y: 0 }, stroke: col, strokeWidth: t4.barWidth, strokeOpacity: 0.9, strokeLinecap: "round" }),
|
|
60705
|
-
/* @__PURE__ */ jsx$1(Line, { from: { x: x2(r2.lo), y: -4 }, to: { x: x2(r2.lo), y: 4 }, stroke: col, strokeWidth: 1.5 }),
|
|
60706
|
-
/* @__PURE__ */ jsx$1(Line, { from: { x: x2(r2.hi), y: -4 }, to: { x: x2(r2.hi), y: 4 }, stroke: col, strokeWidth: 1.5 }),
|
|
60707
|
-
/* @__PURE__ */ jsx$1(Circle, { cx: x2(r2.est), cy: 0, r: t4.scatterRadius, fill: col, stroke: t4.surface, strokeWidth: 1.8 }),
|
|
60708
|
-
/* @__PURE__ */ jsx$1(ChartLabel, { x: -padL + 2, y: -13, w: padL - 6, align: "left", size: t4.labelSize, weight: 600, color: t4.ink, family: t4.body, ...(rowHelp == null ? void 0 : rowHelp[i]) ? { help: rowHelp[i] } : {}, children: r2.label }),
|
|
60709
|
-
r2.note && /* @__PURE__ */ jsx$1("text", { x: -padL + 2, y: 9, style: svgText(9, t4.faint, t4.body), children: r2.note }),
|
|
60710
|
-
/* @__PURE__ */ jsx$1("text", { x: innerW + padR - 2, y: 4, textAnchor: "end", style: svgText(t4.titleSize, col, t4.mono, 700), children: signed$1(r2.est) })
|
|
60711
|
-
] }, i);
|
|
60712
|
-
}),
|
|
60713
|
-
/* @__PURE__ */ jsx$1(Line, { from: { x: 0, y: innerH }, to: { x: innerW, y: innerH }, stroke: t4.rule, strokeWidth: 1 }),
|
|
60714
|
-
ticks2.map((tk, i) => /* @__PURE__ */ jsxs(Group, { left: Math.max(0, Math.min(innerW, x2(tk))), children: [
|
|
60715
|
-
/* @__PURE__ */ jsx$1(Line, { from: { x: 0, y: innerH }, to: { x: 0, y: innerH + 4 }, stroke: t4.ruleStrong, strokeWidth: 1 }),
|
|
60716
|
-
/* @__PURE__ */ jsx$1("text", { x: 0, y: innerH + 14, textAnchor: anchorAt(tk), style: svgText(t4.labelSize, t4.muted, t4.mono), children: signed$1(tk) })
|
|
60717
|
-
] }, `t${i}`)),
|
|
60718
|
-
unit2 && /* @__PURE__ */ jsx$1("text", { x: innerW / 2, y: innerH + 26, textAnchor: "middle", style: svgText(t4.labelSize, t4.muted, t4.mono), children: unit2 })
|
|
60719
|
-
] }) }) });
|
|
60720
|
-
}
|
|
60721
|
-
function AreaRange({ lo: lo2, mid, hi, xTicks = [], yTicks = [], zero: zero2, tone: toneName, marks = [], height: height2, yFormat = "signed" }) {
|
|
60722
|
-
const t4 = useChartTheme();
|
|
60723
|
-
const [ref, w2] = useMeasuredWidth();
|
|
60724
|
-
const hPx = height2 ?? 100;
|
|
60725
|
-
const col = t4.tone(toneName ?? "brand");
|
|
60726
|
-
const padL = yTicks.length ? 52 : 6;
|
|
60727
|
-
const padR = 12;
|
|
60728
|
-
const padT = marks.length ? 22 : 8;
|
|
60729
|
-
const padB = xTicks.length ? 22 : 12;
|
|
60730
|
-
const innerW = Math.max(0, w2 - padL - padR);
|
|
60731
|
-
const innerH = hPx - padT - padB;
|
|
60732
|
-
const xScale = createLinearScale({ domain: [0, Math.max(1, mid.length - 1)], range: [0, innerW] });
|
|
60733
|
-
const fin = (x2, fallback) => typeof x2 === "number" && Number.isFinite(x2) ? x2 : fallback;
|
|
60734
|
-
const data4 = mid.map((m2, i) => {
|
|
60735
|
-
const mm = fin(m2, 0);
|
|
60736
|
-
return { i, lo: fin(lo2[i], mm), hi: fin(hi[i], mm), mid: mm };
|
|
60737
|
-
});
|
|
60738
|
-
const dataMin = Math.min(...data4.map((d2) => d2.lo), zero2 ?? Infinity);
|
|
60739
|
-
const dataMax = Math.max(...data4.map((d2) => d2.hi), zero2 ?? -Infinity);
|
|
60740
|
-
const yHiN = niceCeil(Math.max(dataMax, 0));
|
|
60741
|
-
const yLoN = dataMin < -0.08 * yHiN ? -niceCeil(-dataMin) : 0;
|
|
60742
|
-
const yScale = createLinearScale({ domain: [yLoN, yHiN], range: [innerH, 0] });
|
|
60743
|
-
const yfmt = (v3) => yFormat === "percent" ? `${Math.round(v3)}%` : signed$1(v3);
|
|
60744
|
-
const yLabels = [yfmt(yHiN), yfmt((yHiN + yLoN) / 2), yfmt(yLoN)];
|
|
60745
|
-
return /* @__PURE__ */ jsx$1(Box, { ref, width: "100%", height: `${hPx}px`, children: w2 > 0 && /* @__PURE__ */ jsx$1("svg", { width: w2, height: hPx, style: { display: "block" }, children: /* @__PURE__ */ jsxs(Group, { left: padL, top: padT, children: [
|
|
60746
|
-
/* @__PURE__ */ jsx$1(Line, { from: { x: 0, y: 0 }, to: { x: 0, y: innerH }, stroke: t4.rule, strokeWidth: 1 }),
|
|
60747
|
-
yTicks.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
60748
|
-
/* @__PURE__ */ jsx$1("text", { x: -8, y: 10, textAnchor: "end", style: svgText(t4.labelSize, t4.muted, t4.mono), children: yLabels[0] }),
|
|
60749
|
-
/* @__PURE__ */ jsx$1("text", { x: -8, y: innerH / 2 + 3, textAnchor: "end", style: svgText(t4.labelSize, t4.muted, t4.mono), children: yLabels[1] }),
|
|
60750
|
-
/* @__PURE__ */ jsx$1("text", { x: -8, y: innerH - 1, textAnchor: "end", style: svgText(t4.labelSize, t4.muted, t4.mono), children: yLabels[2] })
|
|
60751
|
-
] }),
|
|
60752
|
-
zero2 != null && /* @__PURE__ */ jsx$1(Line, { from: { x: 0, y: yScale(zero2) }, to: { x: innerW, y: yScale(zero2) }, stroke: t4.muted, strokeWidth: 1, strokeDasharray: "3 2" }),
|
|
60753
|
-
/* @__PURE__ */ jsx$1(Area, { data: data4, x: (d2) => xScale(d2.i), y0: (d2) => yScale(d2.lo), y1: (d2) => yScale(d2.hi), curve: monotoneX, fill: col, fillOpacity: t4.areaOpacity, stroke: "transparent" }),
|
|
60754
|
-
/* @__PURE__ */ jsx$1(LinePath, { data: data4, x: (d2) => xScale(d2.i), y: (d2) => yScale(d2.mid), curve: monotoneX, stroke: col, strokeWidth: t4.lineWidth }),
|
|
60755
|
-
marks.map((m2, i) => {
|
|
60756
|
-
const mc = t4.tone(m2.tone);
|
|
60757
|
-
const dotY = yScale(fin(mid[m2.at], 0));
|
|
60758
|
-
const labY = Math.max(9, dotY - 9);
|
|
60759
|
-
const atEnd = m2.at >= mid.length - 2;
|
|
60760
|
-
const atStart = m2.at <= 1;
|
|
60761
|
-
const align = atEnd ? "right" : atStart ? "left" : "center";
|
|
60762
|
-
const labW = m2.label.length * 6.5 + 8;
|
|
60763
|
-
const labX = atEnd ? -labW - 5 : atStart ? 5 : -labW / 2;
|
|
60764
|
-
return /* @__PURE__ */ jsxs(Group, { left: xScale(m2.at), children: [
|
|
60765
|
-
/* @__PURE__ */ jsx$1(Line, { from: { x: 0, y: -2 }, to: { x: 0, y: innerH }, stroke: mc, strokeWidth: 1, strokeDasharray: "2 3" }),
|
|
60766
|
-
/* @__PURE__ */ jsx$1(Circle, { cx: 0, cy: dotY, r: t4.dotRadius, fill: mc, stroke: t4.surface, strokeWidth: 1.5 }),
|
|
60767
|
-
/* @__PURE__ */ jsx$1(ChartLabel, { x: labX, y: labY - 11, w: labW, align, size: t4.labelSize, weight: 500, color: mc, family: t4.body, ...m2.help ? { help: m2.help } : {}, children: m2.label })
|
|
60768
|
-
] }, `mk${i}`);
|
|
60769
|
-
}),
|
|
60770
|
-
/* @__PURE__ */ jsx$1(Line, { from: { x: 0, y: innerH }, to: { x: innerW, y: innerH }, stroke: t4.rule, strokeWidth: 1 }),
|
|
60771
|
-
xTicks.map((tk, i) => {
|
|
60772
|
-
const word = Number.isNaN(Number(tk));
|
|
60773
|
-
return /* @__PURE__ */ jsx$1("text", { x: innerW * i / Math.max(1, xTicks.length - 1), y: innerH + 14, textAnchor: i === 0 ? "start" : i === xTicks.length - 1 ? "end" : "middle", style: svgText(word ? 9 : t4.labelSize, word ? t4.faint : t4.muted, word ? t4.body : t4.mono), children: tk }, `x${i}`);
|
|
60774
|
-
})
|
|
60775
|
-
] }) }) });
|
|
60776
|
-
}
|
|
60777
|
-
function OverlapHistogram({ treated, control, domain = [0, 1], supportLabel, positivityOk, height: height2 }) {
|
|
60778
|
-
const t4 = useChartTheme();
|
|
60779
|
-
const [ref, w2] = useMeasuredWidth();
|
|
60780
|
-
const hPx = height2 ?? 150;
|
|
60781
|
-
const padL = 8, padR = 8, padT = 16, padB = 26;
|
|
60782
|
-
const innerW = Math.max(0, w2 - padL - padR);
|
|
60783
|
-
const innerH = hPx - padT - padB;
|
|
60784
|
-
const centerY = innerH / 2;
|
|
60785
|
-
const halfH = centerY - 4;
|
|
60786
|
-
const bins = Math.max(treated.length, control.length);
|
|
60787
|
-
const x2 = createLinearScale({ domain, range: [0, innerW] });
|
|
60788
|
-
const span = domain[1] - domain[0];
|
|
60789
|
-
const binW = bins > 0 ? innerW / bins : innerW;
|
|
60790
|
-
const barW = Math.max(1, binW * 0.78);
|
|
60791
|
-
const maxVal = Math.max(1e-9, ...treated, ...control);
|
|
60792
|
-
const tCol = t4.tone("pos");
|
|
60793
|
-
const cCol = t4.tone("muted");
|
|
60794
|
-
const ticks2 = [domain[0], (domain[0] + domain[1]) / 2, domain[1]];
|
|
60795
|
-
const cx2 = (i) => x2(domain[0] + (i + 0.5) / bins * span);
|
|
60796
|
-
return /* @__PURE__ */ jsx$1(Box, { ref, width: "100%", height: `${hPx}px`, children: w2 > 0 && /* @__PURE__ */ jsx$1("svg", { width: w2, height: hPx, style: { display: "block" }, children: /* @__PURE__ */ jsxs(Group, { left: padL, top: padT, children: [
|
|
60797
|
-
/* @__PURE__ */ jsx$1("text", { x: 0, y: -4, style: svgText(9, t4.faint, t4.body), children: "treated ↑" }),
|
|
60798
|
-
supportLabel && /* @__PURE__ */ jsx$1("text", { x: innerW, y: -4, textAnchor: "end", style: svgText(t4.labelSize, positivityOk ? t4.tone("pos") : t4.tone("warn"), t4.mono, 600), children: supportLabel }),
|
|
60799
|
-
Array.from({ length: bins }, (_2, i) => {
|
|
60800
|
-
const ht = Number(treated[i] ?? 0) / maxVal * halfH;
|
|
60801
|
-
const hc = Number(control[i] ?? 0) / maxVal * halfH;
|
|
60802
|
-
const left = cx2(i) - barW / 2;
|
|
60803
|
-
return /* @__PURE__ */ jsxs(Group, { children: [
|
|
60804
|
-
ht > 0 && /* @__PURE__ */ jsx$1("rect", { x: left, y: centerY - ht, width: barW, height: ht, fill: tCol, fillOpacity: 0.85, rx: 0.5 }),
|
|
60805
|
-
hc > 0 && /* @__PURE__ */ jsx$1("rect", { x: left, y: centerY, width: barW, height: hc, fill: cCol, fillOpacity: 0.6, rx: 0.5 })
|
|
60806
|
-
] }, i);
|
|
60807
|
-
}),
|
|
60808
|
-
/* @__PURE__ */ jsx$1(Line, { from: { x: 0, y: centerY }, to: { x: innerW, y: centerY }, stroke: t4.ruleStrong, strokeWidth: 1 }),
|
|
60809
|
-
/* @__PURE__ */ jsx$1("text", { x: 0, y: innerH + 4, style: svgText(9, t4.faint, t4.body), children: "untreated ↓" }),
|
|
60810
|
-
ticks2.map((tk, i) => /* @__PURE__ */ jsx$1("text", { x: x2(tk), y: innerH + 16, textAnchor: i === 0 ? "start" : i === ticks2.length - 1 ? "end" : "middle", style: svgText(t4.labelSize, t4.muted, t4.mono), children: fmt$2(tk) }, `x${i}`))
|
|
60811
|
-
] }) }) });
|
|
60812
|
-
}
|
|
60813
60978
|
const arr = (v3) => v3 ? Array.from(v3, Number) : [];
|
|
60814
60979
|
const arrI = (v3) => v3 ? Array.from(v3, Number) : [];
|
|
60815
|
-
const
|
|
60816
|
-
|
|
60817
|
-
|
|
60818
|
-
|
|
60819
|
-
const signed = (x2) => {
|
|
60820
|
-
const f2 = fmt$1(x2);
|
|
60821
|
-
return f2 === "0" || f2 === "0.0" || f2.startsWith("-") ? f2 : `+${f2}`;
|
|
60822
|
-
};
|
|
60980
|
+
const ONE_DECIMAL = variant("number", { minimumFractionDigits: some(1n), maximumFractionDigits: some(1n), signDisplay: none$1 });
|
|
60981
|
+
const formatOf = (x2) => Number.isInteger(x2) ? void 0 : ONE_DECIMAL;
|
|
60982
|
+
const fmt$1 = (x2, words) => words.value(Math.abs(x2) < 0.05 ? 0 : x2, formatOf(x2));
|
|
60983
|
+
const signed = (x2, words) => words.value(x2, formatOf(x2), true);
|
|
60823
60984
|
const clamp01 = (x2) => x2 < 0 ? 0 : x2 > 1 ? 1 : x2;
|
|
60985
|
+
const compareFloats = compareFor(FloatType);
|
|
60824
60986
|
function band(absStd) {
|
|
60825
60987
|
if (absStd >= 0.66) return { level: "large gap", tone: "neg" };
|
|
60826
60988
|
if (absStd >= 0.33) return { level: "some", tone: "warn" };
|
|
@@ -60870,7 +61032,7 @@ function treatmentKind(cols, treatment) {
|
|
|
60870
61032
|
return "value";
|
|
60871
61033
|
}
|
|
60872
61034
|
}
|
|
60873
|
-
function deriveSpec(config2, cols, result, meta3, dataLen, subject) {
|
|
61035
|
+
function deriveSpec(config2, cols, result, meta3, dataLen, subject, words) {
|
|
60874
61036
|
const outUnit = unitOf(meta3, config2.outcome);
|
|
60875
61037
|
const balByCol = /* @__PURE__ */ new Map();
|
|
60876
61038
|
for (const b2 of (result == null ? void 0 : result.balance) ?? []) {
|
|
@@ -60908,24 +61070,24 @@ function deriveSpec(config2, cols, result, meta3, dataLen, subject) {
|
|
|
60908
61070
|
// n_total belongs to the Answer-tab counts strip; labelling the header
|
|
60909
61071
|
// with it desyncs from the data after a population edit (and reads
|
|
60910
61072
|
// wrong whenever the two legitimately differ).
|
|
60911
|
-
dataLabel: `${dataLen} ${subject.many}`
|
|
61073
|
+
dataLabel: `${words.number(dataLen)} ${subject.many}`
|
|
60912
61074
|
};
|
|
60913
61075
|
}
|
|
60914
|
-
function balanceDisplay(b2, categorical) {
|
|
61076
|
+
function balanceDisplay(b2, categorical, words) {
|
|
60915
61077
|
const isProp = categorical.has(b2.base_column) && b2.treated_mean >= 0 && b2.treated_mean <= 1 && b2.control_mean >= 0 && b2.control_mean <= 1;
|
|
60916
|
-
return isProp ? `${
|
|
61078
|
+
return isProp ? `${words.percent(b2.treated_mean)} vs ${words.percent(b2.control_mean)}` : `${words.value(b2.treated_mean, ONE_DECIMAL)} vs ${words.value(b2.control_mean, ONE_DECIMAL)}`;
|
|
60917
61079
|
}
|
|
60918
|
-
function deriveAnswer(config2, result, adj, meta3) {
|
|
61080
|
+
function deriveAnswer(config2, result, adj, meta3, words) {
|
|
60919
61081
|
const ci = getSomeorUndefined(adj.ci);
|
|
60920
61082
|
const nci = getSomeorUndefined(result.naive_ci);
|
|
60921
61083
|
const categorical = new Set(getSomeorUndefined(config2.categorical) ?? []);
|
|
60922
|
-
const balance = [...result.balance].sort((a2, b2) => Math.abs(b2.std_diff)
|
|
61084
|
+
const balance = [...result.balance].sort((a2, b2) => compareFloats(Math.abs(b2.std_diff), Math.abs(a2.std_diff))).map((b2) => ({
|
|
60923
61085
|
// One-hot rows are `col=level` — label the BASE confounder, keep the level.
|
|
60924
61086
|
col: b2.column,
|
|
60925
61087
|
label: b2.column === b2.base_column ? labelOf(meta3, b2.base_column) : `${labelOf(meta3, b2.base_column)}${b2.column.startsWith(b2.base_column) ? b2.column.slice(b2.base_column.length) : ` (${b2.column})`}`,
|
|
60926
61088
|
treated: b2.treated_mean,
|
|
60927
61089
|
control: b2.control_mean,
|
|
60928
|
-
display: balanceDisplay(b2, categorical),
|
|
61090
|
+
display: balanceDisplay(b2, categorical, words),
|
|
60929
61091
|
frac: clamp01(Math.abs(b2.std_diff)),
|
|
60930
61092
|
tone: band(Math.abs(b2.std_diff)).tone
|
|
60931
61093
|
}));
|
|
@@ -60956,12 +61118,12 @@ function deriveAnswer(config2, result, adj, meta3) {
|
|
|
60956
61118
|
balance
|
|
60957
61119
|
};
|
|
60958
61120
|
}
|
|
60959
|
-
function deriveNarrative(result, a2, refute, higherBetter, subject) {
|
|
61121
|
+
function deriveNarrative(result, a2, refute, higherBetter, subject, words) {
|
|
60960
61122
|
if (a2 === null) return null;
|
|
60961
61123
|
const unit2 = a2.unit ? ` ${a2.unit}` : "";
|
|
60962
61124
|
const dirUp = a2.effect > 0;
|
|
60963
61125
|
const verb = higherBetter === void 0 ? dirUp ? "raises" : "lowers" : dirUp === higherBetter ? "improves" : "worsens";
|
|
60964
|
-
const range = ` (likely between ${signed(a2.lo)} and ${signed(a2.hi)})`;
|
|
61126
|
+
const range = ` (likely between ${signed(a2.lo, words)} and ${signed(a2.hi, words)})`;
|
|
60965
61127
|
const passed = (refute == null ? void 0 : refute.checks.filter((c2) => c2.passed).length) ?? 0;
|
|
60966
61128
|
const total = (refute == null ? void 0 : refute.checks.length) ?? 0;
|
|
60967
61129
|
const trustClause = total === 0 ? "" : passed === total ? ` It held up against all ${total} ways we tried to break it.` : ` It passed ${passed} of ${total} stress tests — see “Can we trust it?”.`;
|
|
@@ -60972,13 +61134,13 @@ function deriveNarrative(result, a2, refute, higherBetter, subject) {
|
|
|
60972
61134
|
segments: [
|
|
60973
61135
|
{ text: "Yes — ", strong: true },
|
|
60974
61136
|
{ text: `${a2.treatment} genuinely ${verb} ${a2.outcome}: about ` },
|
|
60975
|
-
{ text: `${signed(a2.effect)}${unit2}`, strong: true },
|
|
61137
|
+
{ text: `${signed(a2.effect, words)}${unit2}`, strong: true },
|
|
60976
61138
|
{ text: ` per ${subject.one}${range}.${trustClause}` }
|
|
60977
61139
|
]
|
|
60978
61140
|
};
|
|
60979
61141
|
case "modest": {
|
|
60980
61142
|
const tags = new Set(result.verdict_reasons.map((v3) => v3.type));
|
|
60981
|
-
const why = tags.has("not_material") ? ` — the change (${signed(a2.effect)}${unit2}) is smaller than what would matter here (±${fmt$1(result.materiality_threshold)}${unit2}).` : tags.has("ci_spans_zero") ? ` — the likely range (${signed(a2.lo)} to ${signed(a2.hi)}) includes zero.` : tags.has("thin_support") ? " — too few treated and untreated look-alikes overlap to be confident." : tags.has("low_robustness") ? " — a fairly weak hidden factor could overturn it." : a2.lo <= 0 && a2.hi >= 0 ? ` — the likely range (${signed(a2.lo)} to ${signed(a2.hi)}) includes zero.` : ".";
|
|
61143
|
+
const why = tags.has("not_material") ? ` — the change (${signed(a2.effect, words)}${unit2}) is smaller than what would matter here (±${fmt$1(result.materiality_threshold, words)}${unit2}).` : tags.has("ci_spans_zero") ? ` — the likely range (${signed(a2.lo, words)} to ${signed(a2.hi, words)}) includes zero.` : tags.has("thin_support") ? " — too few treated and untreated look-alikes overlap to be confident." : tags.has("low_robustness") ? " — a fairly weak hidden factor could overturn it." : a2.lo <= 0 && a2.hi >= 0 ? ` — the likely range (${signed(a2.lo, words)} to ${signed(a2.hi, words)}) includes zero.` : ".";
|
|
60982
61144
|
return {
|
|
60983
61145
|
tone: "warn",
|
|
60984
61146
|
segments: [
|
|
@@ -60993,14 +61155,14 @@ function deriveNarrative(result, a2, refute, higherBetter, subject) {
|
|
|
60993
61155
|
tone: "warn",
|
|
60994
61156
|
segments: [
|
|
60995
61157
|
{ text: "Don’t act on this yet — ", strong: true },
|
|
60996
|
-
{ text: `we got a number (${signed(a2.effect)}${unit2}), but a stress test failed: something we didn’t adjust for may still be driving it.` }
|
|
61158
|
+
{ text: `we got a number (${signed(a2.effect, words)}${unit2}), but a stress test failed: something we didn’t adjust for may still be driving it.` }
|
|
60997
61159
|
]
|
|
60998
61160
|
};
|
|
60999
61161
|
default:
|
|
61000
61162
|
return null;
|
|
61001
61163
|
}
|
|
61002
61164
|
}
|
|
61003
|
-
function deriveRefusal(config2, result, meta3, subject) {
|
|
61165
|
+
function deriveRefusal(config2, result, meta3, subject, words) {
|
|
61004
61166
|
const nT = Number(result.n_treated), nC = Number(result.n_control), nTot = Number(result.n_total);
|
|
61005
61167
|
const treatment = labelOf(meta3, config2.treatment);
|
|
61006
61168
|
if (result.verdict.type === "not_estimable") {
|
|
@@ -61010,22 +61172,22 @@ function deriveRefusal(config2, result, meta3, subject) {
|
|
|
61010
61172
|
title: `Can’t estimate the effect of ${treatment}`,
|
|
61011
61173
|
body: reason,
|
|
61012
61174
|
evidence: [
|
|
61013
|
-
{ label: "treated", value:
|
|
61014
|
-
{ label: "untreated", value:
|
|
61015
|
-
{ label: subject.many, value:
|
|
61175
|
+
{ label: "treated", value: words.number(nT) },
|
|
61176
|
+
{ label: "untreated", value: words.number(nC) },
|
|
61177
|
+
{ label: subject.many, value: words.number(nTot) }
|
|
61016
61178
|
]
|
|
61017
61179
|
};
|
|
61018
61180
|
}
|
|
61019
61181
|
if (result.verdict.type === "non_identifiable_positivity") {
|
|
61020
|
-
const pct =
|
|
61182
|
+
const pct = words.percent(result.overlap.common_support_frac);
|
|
61021
61183
|
return {
|
|
61022
61184
|
kind: "positivity",
|
|
61023
61185
|
title: "No like-for-like comparison exists",
|
|
61024
|
-
body: `The treated and untreated groups barely overlap on the confounders — only ${pct}
|
|
61186
|
+
body: `The treated and untreated groups barely overlap on the confounders — only ${pct} sit in a range where both occur — so there is no fair comparison to adjust toward.`,
|
|
61025
61187
|
evidence: [
|
|
61026
|
-
{ label: "common support", value:
|
|
61027
|
-
{ label: "treated", value:
|
|
61028
|
-
{ label: "untreated", value:
|
|
61188
|
+
{ label: "common support", value: pct },
|
|
61189
|
+
{ label: "treated", value: words.number(nT) },
|
|
61190
|
+
{ label: "untreated", value: words.number(nC) }
|
|
61029
61191
|
]
|
|
61030
61192
|
};
|
|
61031
61193
|
}
|
|
@@ -61034,20 +61196,19 @@ function deriveRefusal(config2, result, meta3, subject) {
|
|
|
61034
61196
|
title: `Can’t estimate the effect of ${treatment}`,
|
|
61035
61197
|
body: "The engine could not produce a like-for-like estimate for this configuration.",
|
|
61036
61198
|
evidence: [
|
|
61037
|
-
{ label: "treated", value:
|
|
61038
|
-
{ label: "untreated", value:
|
|
61039
|
-
{ label: subject.many, value:
|
|
61199
|
+
{ label: "treated", value: words.number(nT) },
|
|
61200
|
+
{ label: "untreated", value: words.number(nC) },
|
|
61201
|
+
{ label: subject.many, value: words.number(nTot) }
|
|
61040
61202
|
]
|
|
61041
61203
|
};
|
|
61042
61204
|
}
|
|
61043
|
-
function deriveOverlap(o2) {
|
|
61044
|
-
const pct = Math.round(o2.common_support_frac * 100);
|
|
61205
|
+
function deriveOverlap(o2, words) {
|
|
61045
61206
|
return {
|
|
61046
61207
|
treated: arr(o2.treated_propensity),
|
|
61047
61208
|
control: arr(o2.control_propensity),
|
|
61048
61209
|
commonSupportFrac: o2.common_support_frac,
|
|
61049
61210
|
positivityOk: o2.positivity_ok,
|
|
61050
|
-
supportLabel: `${
|
|
61211
|
+
supportLabel: `${words.percent(o2.common_support_frac)} common support`
|
|
61051
61212
|
};
|
|
61052
61213
|
}
|
|
61053
61214
|
function zeroCrossing(xs, ys) {
|
|
@@ -61060,7 +61221,7 @@ function zeroCrossing(xs, ys) {
|
|
|
61060
61221
|
}
|
|
61061
61222
|
return null;
|
|
61062
61223
|
}
|
|
61063
|
-
function deriveRefute(r2, adj, meta3) {
|
|
61224
|
+
function deriveRefute(r2, adj, meta3, words) {
|
|
61064
61225
|
const checks = [];
|
|
61065
61226
|
const est = (adj == null ? void 0 : adj.effect) ?? 0;
|
|
61066
61227
|
const placeboEffect = getSomeorUndefined(r2.placebo_effect);
|
|
@@ -61073,7 +61234,7 @@ function deriveRefute(r2, adj, meta3) {
|
|
|
61073
61234
|
desc: "Shuffle which rows were treated; a real effect should collapse to zero.",
|
|
61074
61235
|
// Speak the outcome, not the statistic: on fake labels the effect
|
|
61075
61236
|
// should VANISH — say whether it did.
|
|
61076
|
-
value: placeboEffect !== void 0 ? passed ? `vanished (${signed(placeboEffect)})` : `didn’t vanish (${signed(placeboEffect)})` : passed ? "vanished" : "didn’t vanish",
|
|
61237
|
+
value: placeboEffect !== void 0 ? passed ? `vanished (${signed(placeboEffect, words)})` : `didn’t vanish (${signed(placeboEffect, words)})` : passed ? "vanished" : "didn’t vanish",
|
|
61077
61238
|
passed,
|
|
61078
61239
|
tip: some("Randomly re-label which rows were treated. A genuine effect should vanish."),
|
|
61079
61240
|
help: "check_shuffle"
|
|
@@ -61087,7 +61248,7 @@ function deriveRefute(r2, adj, meta3) {
|
|
|
61087
61248
|
name: "Drop-some test",
|
|
61088
61249
|
short: "drop-some",
|
|
61089
61250
|
desc: "Re-estimate on random subsamples; a trustworthy effect stays put.",
|
|
61090
|
-
value: passed ? `stayed at ${signed(ds)} ± ${fmt$1(dstd)}` : `moved to ${signed(ds)} ± ${fmt$1(dstd)}`,
|
|
61251
|
+
value: passed ? `stayed at ${signed(ds, words)} ± ${fmt$1(dstd, words)}` : `moved to ${signed(ds, words)} ± ${fmt$1(dstd, words)}`,
|
|
61091
61252
|
passed,
|
|
61092
61253
|
tip: none$1,
|
|
61093
61254
|
help: "check_dropsome"
|
|
@@ -61107,14 +61268,14 @@ function deriveRefute(r2, adj, meta3) {
|
|
|
61107
61268
|
}
|
|
61108
61269
|
const sens = getSomeorUndefined(r2.sensitivity);
|
|
61109
61270
|
const evalue = getSomeorUndefined(r2.robustness_value);
|
|
61110
|
-
const benchmarks = sens ? [...sens.benchmarks].sort((a2, b2) => b2.strength
|
|
61271
|
+
const benchmarks = sens ? [...sens.benchmarks].sort((a2, b2) => compareFloats(b2.strength, a2.strength)) : [];
|
|
61111
61272
|
if (sens !== void 0 || evalue !== void 0) {
|
|
61112
61273
|
const strengths = sens ? arr(sens.strengths) : [];
|
|
61113
61274
|
const effects = sens ? arr(sens.effects) : [];
|
|
61114
61275
|
const tip = sens ? zeroCrossing(strengths, effects) : null;
|
|
61115
61276
|
const strongest = benchmarks[0];
|
|
61116
|
-
const value = tip !== null ? strongest !== void 0 ? tip > strongest.strength ? `flips only beyond ${labelOf(meta3, strongest.column)}` : `a cause weaker than ${labelOf(meta3, strongest.column)} could flip it` : `would flip at ${fmt$1(tip)}` : evalue !== void 0 ? `holds (E-value ${fmt$1(evalue)})` : "holds throughout";
|
|
61117
|
-
const scaleNote = strongest !== void 0 ? ` For scale, your strongest known factor (${labelOf(meta3, strongest.column)}) sits at ${fmt$1(strongest.strength)} on this axis.` : "";
|
|
61277
|
+
const value = tip !== null ? strongest !== void 0 ? tip > strongest.strength ? `flips only beyond ${labelOf(meta3, strongest.column)}` : `a cause weaker than ${labelOf(meta3, strongest.column)} could flip it` : `would flip at ${fmt$1(tip, words)}` : evalue !== void 0 ? `holds (E-value ${fmt$1(evalue, words)})` : "holds throughout";
|
|
61278
|
+
const scaleNote = strongest !== void 0 ? ` For scale, your strongest known factor (${labelOf(meta3, strongest.column)}) sits at ${fmt$1(strongest.strength, words)} on this axis.` : "";
|
|
61118
61279
|
checks.push({
|
|
61119
61280
|
name: "Hidden cause",
|
|
61120
61281
|
short: "hidden cause",
|
|
@@ -61150,12 +61311,12 @@ function deriveRefute(r2, adj, meta3) {
|
|
|
61150
61311
|
const at = atOf(b2.strength);
|
|
61151
61312
|
return at === null ? [] : [{ at, label: `as strong as ${labelOf(meta3, b2.column)}`, tone: "muted", help: "sensitivity" }];
|
|
61152
61313
|
});
|
|
61153
|
-
sensVM = { lo: lo2, mid, hi, xTicks: ["none", "", "stronger"], yTicks: [fmt$1(yLo), fmt$1((yLo + yHi) / 2), fmt$1(yHi)], marks };
|
|
61314
|
+
sensVM = { lo: lo2, mid, hi, xTicks: ["none", "", "stronger"], yTicks: [fmt$1(yLo, words), fmt$1((yLo + yHi) / 2, words), fmt$1(yHi, words)], marks };
|
|
61154
61315
|
}
|
|
61155
61316
|
}
|
|
61156
61317
|
return { checks, sens: sensVM };
|
|
61157
61318
|
}
|
|
61158
|
-
function deriveDose(dose, config2, meta3) {
|
|
61319
|
+
function deriveDose(dose, config2, meta3, words) {
|
|
61159
61320
|
const grid = arr(dose.grid);
|
|
61160
61321
|
const mid = arr(dose.effect);
|
|
61161
61322
|
const lo2 = getSomeorUndefined(dose.lower) ? arr(getSomeorUndefined(dose.lower)) : mid.slice();
|
|
@@ -61173,17 +61334,17 @@ function deriveDose(dose, config2, meta3) {
|
|
|
61173
61334
|
}
|
|
61174
61335
|
}
|
|
61175
61336
|
const xi = grid.length ? [0, Math.floor(grid.length / 2), grid.length - 1] : [];
|
|
61176
|
-
const xTicks = xi.map((i) => fmt$1(grid[i]));
|
|
61337
|
+
const xTicks = xi.map((i) => fmt$1(grid[i], words));
|
|
61177
61338
|
const yLo = Math.min(0, ...lo2), yHi = Math.max(...hi, 0);
|
|
61178
|
-
const yTicks = [fmt$1(yLo), fmt$1((yLo + yHi) / 2), fmt$1(yHi)];
|
|
61339
|
+
const yTicks = [fmt$1(yLo, words), fmt$1((yLo + yHi) / 2, words), fmt$1(yHi, words)];
|
|
61179
61340
|
const margSteps = marg.slice(1);
|
|
61180
61341
|
let lastStep = margSteps.length - 1;
|
|
61181
61342
|
while (lastStep > 0 && Math.abs(margSteps[lastStep]) < 0.12 * maxMarg) lastStep--;
|
|
61182
|
-
const marginal = margSteps.slice(0, lastStep + 1).map((v3, i) => ({ label:
|
|
61343
|
+
const marginal = margSteps.slice(0, lastStep + 1).map((v3, i) => ({ label: fmt$1(grid[i + 1], words), value: v3, frac: clamp01(Math.abs(v3) / maxMarg) }));
|
|
61183
61344
|
const stepFrom = here < sweet ? here : Math.max(0, sweet - 1);
|
|
61184
61345
|
const gainToSweet = (mid[sweet] ?? 0) - (mid[stepFrom] ?? 0);
|
|
61185
61346
|
const nextGain = sweet + 1 < mid.length ? mid[sweet + 1] - mid[sweet] : 0;
|
|
61186
|
-
const tradeoff = `Going from ${fmt$1(grid[stepFrom] ?? 0)} to ${fmt$1(grid[sweet] ?? 0)} adds ${signed(gainToSweet)}; the next step adds only ${signed(nextGain)}.`;
|
|
61347
|
+
const tradeoff = `Going from ${fmt$1(grid[stepFrom] ?? 0, words)} to ${fmt$1(grid[sweet] ?? 0, words)} adds ${signed(gainToSweet, words)}; the next step adds only ${signed(nextGain, words)}.`;
|
|
61187
61348
|
const marks = [];
|
|
61188
61349
|
if (sizes.length) marks.push({ at: here, label: "you are here", tone: "muted", help: "dose_here" });
|
|
61189
61350
|
marks.push({ at: sweet, label: "sweet spot", tone: "pos", help: "dose_sweet" });
|
|
@@ -61200,7 +61361,7 @@ function deriveDose(dose, config2, meta3) {
|
|
|
61200
61361
|
marks,
|
|
61201
61362
|
// Name the feature in the recommendation — a bare "≈ 5.5" doesn't say
|
|
61202
61363
|
// 5.5 of WHAT.
|
|
61203
|
-
recoLabel: `aim for ${featureLabel} ≈ ${fmt$1(grid[sweet] ?? 0)}${featureUnit ? " " + featureUnit : ""}`,
|
|
61364
|
+
recoLabel: `aim for ${featureLabel} ≈ ${fmt$1(grid[sweet] ?? 0, words)}${featureUnit ? " " + featureUnit : ""}`,
|
|
61204
61365
|
recoEffect: mid[sweet] ?? 0,
|
|
61205
61366
|
recoLo: lo2[sweet] ?? 0,
|
|
61206
61367
|
recoHi: hi[sweet] ?? 0,
|
|
@@ -61209,11 +61370,11 @@ function deriveDose(dose, config2, meta3) {
|
|
|
61209
61370
|
framing: `A different question from the headline: how ${outcomeLabel} responds as ${featureLabel} itself moves.`
|
|
61210
61371
|
};
|
|
61211
61372
|
}
|
|
61212
|
-
function relTime(d2, now2) {
|
|
61373
|
+
function relTime(d2, now2, words) {
|
|
61213
61374
|
const days = Math.floor((now2.getTime() - d2.getTime()) / 864e5);
|
|
61214
61375
|
if (days <= 0) return "today";
|
|
61215
61376
|
if (days === 1) return "yesterday";
|
|
61216
|
-
if (days < 7) return
|
|
61377
|
+
if (days < 7) return words.weekday(d2);
|
|
61217
61378
|
return "last wk";
|
|
61218
61379
|
}
|
|
61219
61380
|
const VERDICT_WORD = {
|
|
@@ -61223,43 +61384,43 @@ const VERDICT_WORD = {
|
|
|
61223
61384
|
non_identifiable_positivity: "no overlap",
|
|
61224
61385
|
not_estimable: "n/a"
|
|
61225
61386
|
};
|
|
61226
|
-
function deriveJournalRow(row, now2, meta3) {
|
|
61387
|
+
function deriveJournalRow(row, now2, meta3, words) {
|
|
61227
61388
|
const adj = getSomeorUndefined(row.adjusted);
|
|
61228
61389
|
return {
|
|
61229
61390
|
treatment: labelOf(meta3, row.config.treatment),
|
|
61230
61391
|
outcome: labelOf(meta3, row.config.outcome),
|
|
61231
61392
|
confounders: row.config.common_causes.map((c2) => labelOf(meta3, c2)).join(", "),
|
|
61232
|
-
effect: adj !== void 0 ? signed(adj) : signed(row.naive),
|
|
61393
|
+
effect: adj !== void 0 ? signed(adj, words) : signed(row.naive, words),
|
|
61233
61394
|
verdict: VERDICT_WORD[row.verdict.type],
|
|
61234
61395
|
verdictTone: VERDICT_TONE[row.verdict.type],
|
|
61235
61396
|
who: row.committed_by,
|
|
61236
|
-
when: relTime(row.committed_at, now2),
|
|
61397
|
+
when: relTime(row.committed_at, now2, words),
|
|
61237
61398
|
// The originating preset id (resolved to a label by the surface); `none` for a
|
|
61238
61399
|
// free-form / pre-presets row.
|
|
61239
61400
|
preset: row.preset
|
|
61240
61401
|
};
|
|
61241
61402
|
}
|
|
61242
|
-
function deriveView(config2, ranConfig, cols, result, journal, meta3, dataLen, now2, subject = { one: "record", many: "records" }) {
|
|
61403
|
+
function deriveView(config2, ranConfig, cols, result, journal, meta3, dataLen, now2, subject = { one: "record", many: "records" }, words = formatters()) {
|
|
61243
61404
|
var _a2;
|
|
61244
61405
|
const adj = result ? getSomeorUndefined(result.adjusted) : void 0;
|
|
61245
61406
|
const refutation = result ? getSomeorUndefined(result.refutation) : void 0;
|
|
61246
61407
|
const doseR = result ? getSomeorUndefined(result.dose_response) : void 0;
|
|
61247
|
-
const answer = result && adj ? deriveAnswer(ranConfig, result, adj, meta3) : null;
|
|
61248
|
-
const refute = refutation ? deriveRefute(refutation, adj, meta3) : null;
|
|
61408
|
+
const answer = result && adj ? deriveAnswer(ranConfig, result, adj, meta3, words) : null;
|
|
61409
|
+
const refute = refutation ? deriveRefute(refutation, adj, meta3, words) : null;
|
|
61249
61410
|
const higherBetter = getSomeorUndefined((_a2 = colMeta(meta3, ranConfig.outcome)) == null ? void 0 : _a2.higherIsBetter);
|
|
61250
61411
|
return {
|
|
61251
61412
|
// The set-up rail reflects the LIVE config (the editor); the result deck
|
|
61252
61413
|
// reflects RANCONFIG — the config that produced `result` — so the result
|
|
61253
61414
|
// strings never drift ahead of the numbers on a live picker edit.
|
|
61254
|
-
spec: deriveSpec(config2, cols, result, meta3, dataLen, subject),
|
|
61415
|
+
spec: deriveSpec(config2, cols, result, meta3, dataLen, subject, words),
|
|
61255
61416
|
verdict: result ? deriveVerdict(result.verdict) : null,
|
|
61256
|
-
narrative: result ? deriveNarrative(result, answer, refute, higherBetter, subject) : null,
|
|
61417
|
+
narrative: result ? deriveNarrative(result, answer, refute, higherBetter, subject, words) : null,
|
|
61257
61418
|
answer,
|
|
61258
|
-
refusal: result && !adj ? deriveRefusal(ranConfig, result, meta3, subject) : null,
|
|
61259
|
-
overlap: result ? deriveOverlap(result.overlap) : null,
|
|
61419
|
+
refusal: result && !adj ? deriveRefusal(ranConfig, result, meta3, subject, words) : null,
|
|
61420
|
+
overlap: result ? deriveOverlap(result.overlap, words) : null,
|
|
61260
61421
|
refute,
|
|
61261
|
-
dose: doseR && doseR.effect.length ? deriveDose(doseR, ranConfig, meta3) : null,
|
|
61262
|
-
journal: journal ? journal.map((r2) => deriveJournalRow(r2, now2, meta3)) : null
|
|
61422
|
+
dose: doseR && doseR.effect.length ? deriveDose(doseR, ranConfig, meta3, words) : null,
|
|
61423
|
+
journal: journal ? journal.map((r2) => deriveJournalRow(r2, now2, meta3, words)) : null
|
|
61263
61424
|
};
|
|
61264
61425
|
}
|
|
61265
61426
|
const DESIGN_HEADLINE = {
|
|
@@ -61278,7 +61439,7 @@ function deriveDesignOption(o2) {
|
|
|
61278
61439
|
treatedShare: o2.treated_share
|
|
61279
61440
|
};
|
|
61280
61441
|
}
|
|
61281
|
-
function deriveDesign(d2, result, ranConfig, meta3) {
|
|
61442
|
+
function deriveDesign(d2, result, ranConfig, meta3, words = formatters()) {
|
|
61282
61443
|
const basis = d2.basis.type;
|
|
61283
61444
|
const outcome = ranConfig.outcome;
|
|
61284
61445
|
const unit2 = unitOf(meta3, outcome);
|
|
@@ -61310,9 +61471,9 @@ function deriveDesign(d2, result, ranConfig, meta3) {
|
|
|
61310
61471
|
}
|
|
61311
61472
|
return bi;
|
|
61312
61473
|
};
|
|
61313
|
-
const xTicks = len ? [
|
|
61474
|
+
const xTicks = len ? [words.number(ns[0]), words.number(ns[Math.floor((len - 1) / 2)]), words.number(ns[len - 1])] : [];
|
|
61314
61475
|
const marks = [];
|
|
61315
|
-
if (len) marks.push({ at: nearest(primary.nTotal), label: `target ${(d2.target_power
|
|
61476
|
+
if (len) marks.push({ at: nearest(primary.nTotal), label: `target ${words.percent(d2.target_power)}`, tone: "pos", help: "validate_power" });
|
|
61316
61477
|
const cp = getSomeorUndefined(d2.current_power);
|
|
61317
61478
|
if (cp !== void 0 && len) {
|
|
61318
61479
|
const curN = result ? Number(result.n_total) : 0;
|
|
@@ -61320,7 +61481,7 @@ function deriveDesign(d2, result, ranConfig, meta3) {
|
|
|
61320
61481
|
const offScale = curN >= (ns[len - 1] ?? 0);
|
|
61321
61482
|
marks.push({
|
|
61322
61483
|
at: offScale ? len - 1 : nearest(curN),
|
|
61323
|
-
label: offScale ? `you’re here · ${(cp
|
|
61484
|
+
label: offScale ? `you’re here · ${words.percent(cp)} (off-scale)` : `you’re here ${words.percent(cp)}`,
|
|
61324
61485
|
tone: "muted",
|
|
61325
61486
|
help: "validate_power"
|
|
61326
61487
|
});
|
|
@@ -61334,13 +61495,204 @@ function deriveDesign(d2, result, ranConfig, meta3) {
|
|
|
61334
61495
|
alternates: options2.slice(1),
|
|
61335
61496
|
matchOn,
|
|
61336
61497
|
curve: { mid: powers.slice(0, len).map((p2) => p2 * 100), xTicks, marks },
|
|
61337
|
-
targetLabel: `${signed(d2.target_effect)}${unit2 ? ` ${unit2}` : ""}`,
|
|
61338
|
-
targetPctLabel:
|
|
61498
|
+
targetLabel: `${signed(d2.target_effect, words)}${unit2 ? ` ${unit2}` : ""}`,
|
|
61499
|
+
targetPctLabel: words.percent(d2.target_power),
|
|
61339
61500
|
holdback: basis === "create_control",
|
|
61340
61501
|
showOverlap: basis === "restrict_to_overlap",
|
|
61341
61502
|
faint
|
|
61342
61503
|
};
|
|
61343
61504
|
}
|
|
61505
|
+
function ChartLabel({ x: x2, y: y2, w: w2, align, size: size3, weight: weight8, color: color2, family, help, children: children2 }) {
|
|
61506
|
+
const span = /* @__PURE__ */ jsx$1("span", { style: { fontSize: `${size3}px`, fontFamily: family, fontWeight: weight8, color: color2, lineHeight: 1, whiteSpace: "nowrap" }, children: children2 });
|
|
61507
|
+
return /* @__PURE__ */ jsx$1("foreignObject", { x: x2, y: y2, width: w2, height: size3 + 6, style: { overflow: "visible" }, children: /* @__PURE__ */ jsx$1("div", { style: { textAlign: align, fontSize: `${size3}px`, lineHeight: 1 }, children: help ? /* @__PURE__ */ jsx$1(Help, { id: help, children: span }) : span }) });
|
|
61508
|
+
}
|
|
61509
|
+
function svgText(size3, fill, family, weight8) {
|
|
61510
|
+
return { fontSize: `${size3}px`, fill, fontFamily: family, ...weight8 !== void 0 ? { fontWeight: weight8 } : {} };
|
|
61511
|
+
}
|
|
61512
|
+
function useMeasuredWidth() {
|
|
61513
|
+
const ref = useRef(null);
|
|
61514
|
+
const [w2, setW] = useState(0);
|
|
61515
|
+
useLayoutEffect(() => {
|
|
61516
|
+
const el = ref.current;
|
|
61517
|
+
if (!el) return;
|
|
61518
|
+
const update2 = () => setW(el.clientWidth);
|
|
61519
|
+
update2();
|
|
61520
|
+
const ro = new ResizeObserver(update2);
|
|
61521
|
+
ro.observe(el);
|
|
61522
|
+
return () => ro.disconnect();
|
|
61523
|
+
}, []);
|
|
61524
|
+
return [ref, w2];
|
|
61525
|
+
}
|
|
61526
|
+
function useChartTheme() {
|
|
61527
|
+
const system = useChakraContext();
|
|
61528
|
+
const tok = (k2, fallback) => system.token(k2, fallback);
|
|
61529
|
+
const tones = {
|
|
61530
|
+
neg: tok("colors.fg.danger", "#b85a4a"),
|
|
61531
|
+
pos: tok("colors.fg.success", "#2f7a5b"),
|
|
61532
|
+
warn: tok("colors.fg.warning", "#b8862d"),
|
|
61533
|
+
muted: tok("colors.fg.muted", "#6b8080"),
|
|
61534
|
+
brand: tok("colors.brand.solid", "#3a7780")
|
|
61535
|
+
};
|
|
61536
|
+
return {
|
|
61537
|
+
mono: tok("fonts.mono", '"JetBrains Mono", ui-monospace, monospace'),
|
|
61538
|
+
body: tok("fonts.body", "system-ui, -apple-system, sans-serif"),
|
|
61539
|
+
ink: tok("colors.fg", "#111b22"),
|
|
61540
|
+
muted: tones.muted,
|
|
61541
|
+
faint: tok("colors.fg.subtle", "#9bb0b0"),
|
|
61542
|
+
rule: tok("colors.border.subtle", "#e2e8e8"),
|
|
61543
|
+
ruleStrong: tok("colors.border.strong", "#cbd5d5"),
|
|
61544
|
+
surface: tok("colors.bg.surface", "#ffffff"),
|
|
61545
|
+
tone: (t4) => tones[t4] ?? tones.brand,
|
|
61546
|
+
labelSize: 10,
|
|
61547
|
+
titleSize: 11,
|
|
61548
|
+
lineWidth: 1.8,
|
|
61549
|
+
barWidth: 2.5,
|
|
61550
|
+
dotRadius: 2.6,
|
|
61551
|
+
scatterRadius: 3.4,
|
|
61552
|
+
areaOpacity: 0.16
|
|
61553
|
+
};
|
|
61554
|
+
}
|
|
61555
|
+
const niceCeil = (v3) => {
|
|
61556
|
+
if (v3 <= 1e-9) return 0;
|
|
61557
|
+
const mag = Math.pow(10, Math.floor(Math.log10(v3)));
|
|
61558
|
+
const n2 = v3 / mag;
|
|
61559
|
+
const step3 = n2 <= 1 ? 1 : n2 <= 1.5 ? 1.5 : n2 <= 2 ? 2 : n2 <= 3 ? 3 : n2 <= 4 ? 4 : n2 <= 5 ? 5 : n2 <= 6 ? 6 : n2 <= 8 ? 8 : 10;
|
|
61560
|
+
return step3 * mag;
|
|
61561
|
+
};
|
|
61562
|
+
function ForestPlot({ rows, min: min4, max: max5, unit: unit2, height: height2, rowHelp }) {
|
|
61563
|
+
const t4 = useChartTheme();
|
|
61564
|
+
const words = useFormatters();
|
|
61565
|
+
const [ref, w2] = useMeasuredWidth();
|
|
61566
|
+
const n2 = rows.length;
|
|
61567
|
+
const hPx = height2 ?? 26 + n2 * 38;
|
|
61568
|
+
const padL = 124, padR = 46, padT = 20, padB = 30;
|
|
61569
|
+
const innerW = Math.max(0, w2 - padL - padR);
|
|
61570
|
+
const innerH = hPx - padT - padB;
|
|
61571
|
+
const x2 = createLinearScale({ domain: [min4, max5], range: [0, innerW] });
|
|
61572
|
+
const rowH = innerH / Math.max(1, n2);
|
|
61573
|
+
const zeroX = Math.max(0, Math.min(innerW, x2(0)));
|
|
61574
|
+
const frac = (v3) => max5 > min4 ? (v3 - min4) / (max5 - min4) : 0.5;
|
|
61575
|
+
const anchorAt = (v3) => frac(v3) < 0.06 ? "start" : frac(v3) > 0.94 ? "end" : "middle";
|
|
61576
|
+
const zf = frac(0);
|
|
61577
|
+
const ticks2 = zf > 0.12 && zf < 0.88 ? [min4, 0, max5] : [min4, max5];
|
|
61578
|
+
return /* @__PURE__ */ jsx$1(Box, { ref, width: "100%", height: `${hPx}px`, children: w2 > 0 && /* @__PURE__ */ jsx$1("svg", { width: w2, height: hPx, style: { display: "block" }, children: /* @__PURE__ */ jsxs(Group, { left: padL, top: padT, children: [
|
|
61579
|
+
/* @__PURE__ */ jsx$1(Line, { from: { x: zeroX, y: -4 }, to: { x: zeroX, y: innerH }, stroke: t4.muted, strokeWidth: 1, strokeDasharray: "3 2" }),
|
|
61580
|
+
/* @__PURE__ */ jsx$1("text", { x: zeroX, y: -6, textAnchor: anchorAt(0), style: svgText(t4.labelSize, t4.muted, t4.mono), children: "no effect" }),
|
|
61581
|
+
rows.map((r2, i) => {
|
|
61582
|
+
const cy = rowH * i + rowH / 2;
|
|
61583
|
+
const col = t4.tone(r2.tone);
|
|
61584
|
+
return /* @__PURE__ */ jsxs(Group, { top: cy, children: [
|
|
61585
|
+
/* @__PURE__ */ jsx$1(Line, { from: { x: x2(r2.lo), y: 0 }, to: { x: x2(r2.hi), y: 0 }, stroke: col, strokeWidth: t4.barWidth, strokeOpacity: 0.9, strokeLinecap: "round" }),
|
|
61586
|
+
/* @__PURE__ */ jsx$1(Line, { from: { x: x2(r2.lo), y: -4 }, to: { x: x2(r2.lo), y: 4 }, stroke: col, strokeWidth: 1.5 }),
|
|
61587
|
+
/* @__PURE__ */ jsx$1(Line, { from: { x: x2(r2.hi), y: -4 }, to: { x: x2(r2.hi), y: 4 }, stroke: col, strokeWidth: 1.5 }),
|
|
61588
|
+
/* @__PURE__ */ jsx$1(Circle, { cx: x2(r2.est), cy: 0, r: t4.scatterRadius, fill: col, stroke: t4.surface, strokeWidth: 1.8 }),
|
|
61589
|
+
/* @__PURE__ */ jsx$1(ChartLabel, { x: -padL + 2, y: -13, w: padL - 6, align: "left", size: t4.labelSize, weight: 600, color: t4.ink, family: t4.body, ...(rowHelp == null ? void 0 : rowHelp[i]) ? { help: rowHelp[i] } : {}, children: r2.label }),
|
|
61590
|
+
r2.note && /* @__PURE__ */ jsx$1("text", { x: -padL + 2, y: 9, style: svgText(9, t4.faint, t4.body), children: r2.note }),
|
|
61591
|
+
/* @__PURE__ */ jsx$1("text", { x: innerW + padR - 2, y: 4, textAnchor: "end", style: svgText(t4.titleSize, col, t4.mono, 700), children: signed(r2.est, words) })
|
|
61592
|
+
] }, i);
|
|
61593
|
+
}),
|
|
61594
|
+
/* @__PURE__ */ jsx$1(Line, { from: { x: 0, y: innerH }, to: { x: innerW, y: innerH }, stroke: t4.rule, strokeWidth: 1 }),
|
|
61595
|
+
ticks2.map((tk, i) => /* @__PURE__ */ jsxs(Group, { left: Math.max(0, Math.min(innerW, x2(tk))), children: [
|
|
61596
|
+
/* @__PURE__ */ jsx$1(Line, { from: { x: 0, y: innerH }, to: { x: 0, y: innerH + 4 }, stroke: t4.ruleStrong, strokeWidth: 1 }),
|
|
61597
|
+
/* @__PURE__ */ jsx$1("text", { x: 0, y: innerH + 14, textAnchor: anchorAt(tk), style: svgText(t4.labelSize, t4.muted, t4.mono), children: signed(tk, words) })
|
|
61598
|
+
] }, `t${i}`)),
|
|
61599
|
+
unit2 && /* @__PURE__ */ jsx$1("text", { x: innerW / 2, y: innerH + 26, textAnchor: "middle", style: svgText(t4.labelSize, t4.muted, t4.mono), children: unit2 })
|
|
61600
|
+
] }) }) });
|
|
61601
|
+
}
|
|
61602
|
+
function AreaRange({ lo: lo2, mid, hi, xTicks = [], xTickWords = false, yTicks = [], zero: zero2, tone: toneName, marks = [], height: height2, yFormat = "signed" }) {
|
|
61603
|
+
const t4 = useChartTheme();
|
|
61604
|
+
const words = useFormatters();
|
|
61605
|
+
const [ref, w2] = useMeasuredWidth();
|
|
61606
|
+
const hPx = height2 ?? 100;
|
|
61607
|
+
const col = t4.tone(toneName ?? "brand");
|
|
61608
|
+
const padL = yTicks.length ? 52 : 6;
|
|
61609
|
+
const padR = 12;
|
|
61610
|
+
const padT = marks.length ? 22 : 8;
|
|
61611
|
+
const padB = xTicks.length ? 22 : 12;
|
|
61612
|
+
const innerW = Math.max(0, w2 - padL - padR);
|
|
61613
|
+
const innerH = hPx - padT - padB;
|
|
61614
|
+
const xScale = createLinearScale({ domain: [0, Math.max(1, mid.length - 1)], range: [0, innerW] });
|
|
61615
|
+
const fin = (x2, fallback) => typeof x2 === "number" && Number.isFinite(x2) ? x2 : fallback;
|
|
61616
|
+
const data4 = mid.map((m2, i) => {
|
|
61617
|
+
const mm = fin(m2, 0);
|
|
61618
|
+
return { i, lo: fin(lo2[i], mm), hi: fin(hi[i], mm), mid: mm };
|
|
61619
|
+
});
|
|
61620
|
+
const dataMin = Math.min(...data4.map((d2) => d2.lo), zero2 ?? Infinity);
|
|
61621
|
+
const dataMax = Math.max(...data4.map((d2) => d2.hi), zero2 ?? -Infinity);
|
|
61622
|
+
const yHiN = niceCeil(Math.max(dataMax, 0));
|
|
61623
|
+
const yLoN = dataMin < -0.08 * yHiN ? -niceCeil(-dataMin) : 0;
|
|
61624
|
+
const yScale = createLinearScale({ domain: [yLoN, yHiN], range: [innerH, 0] });
|
|
61625
|
+
const yfmt = (v3) => yFormat === "percent" ? words.percent(v3 / 100) : signed(v3, words);
|
|
61626
|
+
const yLabels = [yfmt(yHiN), yfmt((yHiN + yLoN) / 2), yfmt(yLoN)];
|
|
61627
|
+
return /* @__PURE__ */ jsx$1(Box, { ref, width: "100%", height: `${hPx}px`, children: w2 > 0 && /* @__PURE__ */ jsx$1("svg", { width: w2, height: hPx, style: { display: "block" }, children: /* @__PURE__ */ jsxs(Group, { left: padL, top: padT, children: [
|
|
61628
|
+
/* @__PURE__ */ jsx$1(Line, { from: { x: 0, y: 0 }, to: { x: 0, y: innerH }, stroke: t4.rule, strokeWidth: 1 }),
|
|
61629
|
+
yTicks.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
61630
|
+
/* @__PURE__ */ jsx$1("text", { x: -8, y: 10, textAnchor: "end", style: svgText(t4.labelSize, t4.muted, t4.mono), children: yLabels[0] }),
|
|
61631
|
+
/* @__PURE__ */ jsx$1("text", { x: -8, y: innerH / 2 + 3, textAnchor: "end", style: svgText(t4.labelSize, t4.muted, t4.mono), children: yLabels[1] }),
|
|
61632
|
+
/* @__PURE__ */ jsx$1("text", { x: -8, y: innerH - 1, textAnchor: "end", style: svgText(t4.labelSize, t4.muted, t4.mono), children: yLabels[2] })
|
|
61633
|
+
] }),
|
|
61634
|
+
zero2 != null && /* @__PURE__ */ jsx$1(Line, { from: { x: 0, y: yScale(zero2) }, to: { x: innerW, y: yScale(zero2) }, stroke: t4.muted, strokeWidth: 1, strokeDasharray: "3 2" }),
|
|
61635
|
+
/* @__PURE__ */ jsx$1(Area, { data: data4, x: (d2) => xScale(d2.i), y0: (d2) => yScale(d2.lo), y1: (d2) => yScale(d2.hi), curve: monotoneX, fill: col, fillOpacity: t4.areaOpacity, stroke: "transparent" }),
|
|
61636
|
+
/* @__PURE__ */ jsx$1(LinePath, { data: data4, x: (d2) => xScale(d2.i), y: (d2) => yScale(d2.mid), curve: monotoneX, stroke: col, strokeWidth: t4.lineWidth }),
|
|
61637
|
+
marks.map((m2, i) => {
|
|
61638
|
+
const mc = t4.tone(m2.tone);
|
|
61639
|
+
const dotY = yScale(fin(mid[m2.at], 0));
|
|
61640
|
+
const labY = Math.max(9, dotY - 9);
|
|
61641
|
+
const atEnd = m2.at >= mid.length - 2;
|
|
61642
|
+
const atStart = m2.at <= 1;
|
|
61643
|
+
const align = atEnd ? "right" : atStart ? "left" : "center";
|
|
61644
|
+
const labW = m2.label.length * 6.5 + 8;
|
|
61645
|
+
const labX = atEnd ? -labW - 5 : atStart ? 5 : -labW / 2;
|
|
61646
|
+
return /* @__PURE__ */ jsxs(Group, { left: xScale(m2.at), children: [
|
|
61647
|
+
/* @__PURE__ */ jsx$1(Line, { from: { x: 0, y: -2 }, to: { x: 0, y: innerH }, stroke: mc, strokeWidth: 1, strokeDasharray: "2 3" }),
|
|
61648
|
+
/* @__PURE__ */ jsx$1(Circle, { cx: 0, cy: dotY, r: t4.dotRadius, fill: mc, stroke: t4.surface, strokeWidth: 1.5 }),
|
|
61649
|
+
/* @__PURE__ */ jsx$1(ChartLabel, { x: labX, y: labY - 11, w: labW, align, size: t4.labelSize, weight: 500, color: mc, family: t4.body, ...m2.help ? { help: m2.help } : {}, children: m2.label })
|
|
61650
|
+
] }, `mk${i}`);
|
|
61651
|
+
}),
|
|
61652
|
+
/* @__PURE__ */ jsx$1(Line, { from: { x: 0, y: innerH }, to: { x: innerW, y: innerH }, stroke: t4.rule, strokeWidth: 1 }),
|
|
61653
|
+
xTicks.map((tk, i) => {
|
|
61654
|
+
const word = xTickWords;
|
|
61655
|
+
return /* @__PURE__ */ jsx$1("text", { x: innerW * i / Math.max(1, xTicks.length - 1), y: innerH + 14, textAnchor: i === 0 ? "start" : i === xTicks.length - 1 ? "end" : "middle", style: svgText(word ? 9 : t4.labelSize, word ? t4.faint : t4.muted, word ? t4.body : t4.mono), children: tk }, `x${i}`);
|
|
61656
|
+
})
|
|
61657
|
+
] }) }) });
|
|
61658
|
+
}
|
|
61659
|
+
function OverlapHistogram({ treated, control, domain = [0, 1], supportLabel, positivityOk, height: height2 }) {
|
|
61660
|
+
const t4 = useChartTheme();
|
|
61661
|
+
const words = useFormatters();
|
|
61662
|
+
const [ref, w2] = useMeasuredWidth();
|
|
61663
|
+
const hPx = height2 ?? 150;
|
|
61664
|
+
const padL = 8, padR = 8, padT = 16, padB = 26;
|
|
61665
|
+
const innerW = Math.max(0, w2 - padL - padR);
|
|
61666
|
+
const innerH = hPx - padT - padB;
|
|
61667
|
+
const centerY = innerH / 2;
|
|
61668
|
+
const halfH = centerY - 4;
|
|
61669
|
+
const bins = Math.max(treated.length, control.length);
|
|
61670
|
+
const x2 = createLinearScale({ domain, range: [0, innerW] });
|
|
61671
|
+
const span = domain[1] - domain[0];
|
|
61672
|
+
const binW = bins > 0 ? innerW / bins : innerW;
|
|
61673
|
+
const barW = Math.max(1, binW * 0.78);
|
|
61674
|
+
const maxVal = Math.max(1e-9, ...treated, ...control);
|
|
61675
|
+
const tCol = t4.tone("pos");
|
|
61676
|
+
const cCol = t4.tone("muted");
|
|
61677
|
+
const ticks2 = [domain[0], (domain[0] + domain[1]) / 2, domain[1]];
|
|
61678
|
+
const cx2 = (i) => x2(domain[0] + (i + 0.5) / bins * span);
|
|
61679
|
+
return /* @__PURE__ */ jsx$1(Box, { ref, width: "100%", height: `${hPx}px`, children: w2 > 0 && /* @__PURE__ */ jsx$1("svg", { width: w2, height: hPx, style: { display: "block" }, children: /* @__PURE__ */ jsxs(Group, { left: padL, top: padT, children: [
|
|
61680
|
+
/* @__PURE__ */ jsx$1("text", { x: 0, y: -4, style: svgText(9, t4.faint, t4.body), children: "treated ↑" }),
|
|
61681
|
+
supportLabel && /* @__PURE__ */ jsx$1("text", { x: innerW, y: -4, textAnchor: "end", style: svgText(t4.labelSize, positivityOk ? t4.tone("pos") : t4.tone("warn"), t4.mono, 600), children: supportLabel }),
|
|
61682
|
+
Array.from({ length: bins }, (_2, i) => {
|
|
61683
|
+
const ht = Number(treated[i] ?? 0) / maxVal * halfH;
|
|
61684
|
+
const hc = Number(control[i] ?? 0) / maxVal * halfH;
|
|
61685
|
+
const left = cx2(i) - barW / 2;
|
|
61686
|
+
return /* @__PURE__ */ jsxs(Group, { children: [
|
|
61687
|
+
ht > 0 && /* @__PURE__ */ jsx$1("rect", { x: left, y: centerY - ht, width: barW, height: ht, fill: tCol, fillOpacity: 0.85, rx: 0.5 }),
|
|
61688
|
+
hc > 0 && /* @__PURE__ */ jsx$1("rect", { x: left, y: centerY, width: barW, height: hc, fill: cCol, fillOpacity: 0.6, rx: 0.5 })
|
|
61689
|
+
] }, i);
|
|
61690
|
+
}),
|
|
61691
|
+
/* @__PURE__ */ jsx$1(Line, { from: { x: 0, y: centerY }, to: { x: innerW, y: centerY }, stroke: t4.ruleStrong, strokeWidth: 1 }),
|
|
61692
|
+
/* @__PURE__ */ jsx$1("text", { x: 0, y: innerH + 4, style: svgText(9, t4.faint, t4.body), children: "untreated ↓" }),
|
|
61693
|
+
ticks2.map((tk, i) => /* @__PURE__ */ jsx$1("text", { x: x2(tk), y: innerH + 16, textAnchor: i === 0 ? "start" : i === ticks2.length - 1 ? "end" : "middle", style: svgText(t4.labelSize, t4.muted, t4.mono), children: fmt$1(tk, words) }, `x${i}`))
|
|
61694
|
+
] }) }) });
|
|
61695
|
+
}
|
|
61344
61696
|
const SUBJECT_DEFAULT = { one: "record", many: "records" };
|
|
61345
61697
|
const AUTORUN_MAX_ROWS = 5e4;
|
|
61346
61698
|
const TONE_TOKEN = {
|
|
@@ -61368,7 +61720,7 @@ function kindOfTypeValue(t4) {
|
|
|
61368
61720
|
}
|
|
61369
61721
|
}
|
|
61370
61722
|
function useColumns(workspace, source) {
|
|
61371
|
-
const types =
|
|
61723
|
+
const types = getBindingTypes(workspace, source);
|
|
61372
61724
|
return useMemo(() => {
|
|
61373
61725
|
const st = types == null ? void 0 : types.sourceType;
|
|
61374
61726
|
if (!st || st.type !== "Array") return { columns: [], rowArrayType: null };
|
|
@@ -61380,35 +61732,9 @@ function useColumns(workspace, source) {
|
|
|
61380
61732
|
};
|
|
61381
61733
|
}, [types == null ? void 0 : types.sourceType]);
|
|
61382
61734
|
}
|
|
61383
|
-
function
|
|
61384
|
-
return
|
|
61385
|
-
const { fieldId, op } = p2.value;
|
|
61386
|
-
const v3 = row[fieldId];
|
|
61387
|
-
const ov = op.value;
|
|
61388
|
-
switch (op.type) {
|
|
61389
|
-
case "eq":
|
|
61390
|
-
case "is":
|
|
61391
|
-
return v3 === ov;
|
|
61392
|
-
case "neq":
|
|
61393
|
-
return v3 !== ov;
|
|
61394
|
-
case "lt":
|
|
61395
|
-
return num(v3) != null && num(ov) != null ? num(v3) < num(ov) : true;
|
|
61396
|
-
case "lte":
|
|
61397
|
-
return num(v3) != null && num(ov) != null ? num(v3) <= num(ov) : true;
|
|
61398
|
-
case "gt":
|
|
61399
|
-
return num(v3) != null && num(ov) != null ? num(v3) > num(ov) : true;
|
|
61400
|
-
case "gte":
|
|
61401
|
-
return num(v3) != null && num(ov) != null ? num(v3) >= num(ov) : true;
|
|
61402
|
-
case "in":
|
|
61403
|
-
return isEastSet(ov) ? ov.has(v3) : true;
|
|
61404
|
-
case "notIn":
|
|
61405
|
-
return isEastSet(ov) ? !ov.has(v3) : true;
|
|
61406
|
-
default:
|
|
61407
|
-
return true;
|
|
61408
|
-
}
|
|
61409
|
-
});
|
|
61735
|
+
function inPopulation(row, population) {
|
|
61736
|
+
return population.every((p2) => slicePredicateMatches(p2, row));
|
|
61410
61737
|
}
|
|
61411
|
-
const num = (x2) => typeof x2 === "number" ? x2 : typeof x2 === "bigint" ? Number(x2) : null;
|
|
61412
61738
|
function Cap({ children: children2, help }) {
|
|
61413
61739
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
61414
61740
|
/* @__PURE__ */ jsx$1(Text, { textStyle: "caption.eyebrow", fontSize: "9px", mb: "2.5", children: help ? /* @__PURE__ */ jsx$1(Help, { id: help, children: children2 }) : children2 }),
|
|
@@ -61521,7 +61847,7 @@ function LoadingSkeleton() {
|
|
|
61521
61847
|
] })
|
|
61522
61848
|
] });
|
|
61523
61849
|
}
|
|
61524
|
-
const experimentValueEqual =
|
|
61850
|
+
const experimentValueEqual = equivalentFor(Experiment.Component.schema);
|
|
61525
61851
|
const EastChakraExperiment = memo(function EastChakraExperiment2({ value }) {
|
|
61526
61852
|
var _a2, _b2, _c2;
|
|
61527
61853
|
const v3 = value;
|
|
@@ -61531,6 +61857,7 @@ const EastChakraExperiment = memo(function EastChakraExperiment2({ value }) {
|
|
|
61531
61857
|
const bs = useSlotRecipe({ key: "barStrip" })({});
|
|
61532
61858
|
const statusR = useSlotRecipe({ key: "status" });
|
|
61533
61859
|
const es = useSlotRecipe({ key: "eyebrowRow" })({});
|
|
61860
|
+
const words = useFormatters();
|
|
61534
61861
|
const workspace = getReactiveDatasetCache().getConfig().workspace ?? "";
|
|
61535
61862
|
const data4 = useBindingValue(v3.data);
|
|
61536
61863
|
const journalBind = useBindingValue(v3.journal.type === "some" ? v3.journal.value : null);
|
|
@@ -61578,7 +61905,7 @@ const EastChakraExperiment = memo(function EastChakraExperiment2({ value }) {
|
|
|
61578
61905
|
const population = localPop;
|
|
61579
61906
|
const filteredRows = useMemo(() => {
|
|
61580
61907
|
if (!data4.value) return null;
|
|
61581
|
-
return population.length ? data4.value.filter((r2) =>
|
|
61908
|
+
return population.length ? data4.value.filter((r2) => inPopulation(r2, population)) : data4.value;
|
|
61582
61909
|
}, [data4.value, population]);
|
|
61583
61910
|
const fields = useMemo(
|
|
61584
61911
|
() => columns.filter((c2) => c2.kind !== "other").map((c2) => {
|
|
@@ -61680,8 +62007,8 @@ const EastChakraExperiment = memo(function EastChakraExperiment2({ value }) {
|
|
|
61680
62007
|
}, [ranConfig, config2, meta3, subject]);
|
|
61681
62008
|
const view = useMemo(() => {
|
|
61682
62009
|
if (!config2) return null;
|
|
61683
|
-
return deriveView(config2, ranConfig ?? config2, columns, shownResult, journalBind.value, meta3, nRows, now2, subject);
|
|
61684
|
-
}, [config2, ranConfig, columns, shownResult, journalBind.value, meta3, nRows, now2, subject]);
|
|
62010
|
+
return deriveView(config2, ranConfig ?? config2, columns, shownResult, journalBind.value, meta3, nRows, now2, subject, words);
|
|
62011
|
+
}, [config2, ranConfig, columns, shownResult, journalBind.value, meta3, nRows, now2, subject, words]);
|
|
61685
62012
|
const designConfigValue = useMemo(() => ({
|
|
61686
62013
|
alpha: none$1,
|
|
61687
62014
|
target_power: none$1,
|
|
@@ -61694,15 +62021,15 @@ const EastChakraExperiment = memo(function EastChakraExperiment2({ value }) {
|
|
|
61694
62021
|
var _a3;
|
|
61695
62022
|
if (tab !== "validate" || !hasDesign || design.pending || precomputedDesign !== null) return;
|
|
61696
62023
|
if (!filteredRows || !config2 || !shownResult) return;
|
|
61697
|
-
if (((_a3 = designSnapRef.current) == null ? void 0 : _a3.result
|
|
62024
|
+
if (Object.is((_a3 = designSnapRef.current) == null ? void 0 : _a3.result, shownResult)) return;
|
|
61698
62025
|
designSnapRef.current = { result: shownResult, config: ranConfig ?? config2 };
|
|
61699
62026
|
design.call(filteredRows, ranConfig ?? config2, shownResult, designConfigValue);
|
|
61700
62027
|
}, [tab, hasDesign, precomputedDesign, filteredRows, config2, ranConfig, shownResult, design, designConfigValue]);
|
|
61701
62028
|
const vmDesign = useMemo(() => {
|
|
61702
|
-
if (precomputedDesign !== null && shownResult !== null && config2) return deriveDesign(precomputedDesign, shownResult, ranConfig ?? config2, meta3);
|
|
61703
|
-
return design.result && designSnapRef.current ? deriveDesign(design.result, designSnapRef.current.result, designSnapRef.current.config, meta3) : null;
|
|
61704
|
-
}, [precomputedDesign, shownResult, config2, ranConfig, design.result, meta3]);
|
|
61705
|
-
const designFresh = precomputedDesign !== null && shownResult !== null || design.result !== null && ((_b2 = designSnapRef.current) == null ? void 0 : _b2.result
|
|
62029
|
+
if (precomputedDesign !== null && shownResult !== null && config2) return deriveDesign(precomputedDesign, shownResult, ranConfig ?? config2, meta3, words);
|
|
62030
|
+
return design.result && designSnapRef.current ? deriveDesign(design.result, designSnapRef.current.result, designSnapRef.current.config, meta3, words) : null;
|
|
62031
|
+
}, [precomputedDesign, shownResult, config2, ranConfig, design.result, meta3, words]);
|
|
62032
|
+
const designFresh = precomputedDesign !== null && shownResult !== null || design.result !== null && Object.is((_b2 = designSnapRef.current) == null ? void 0 : _b2.result, shownResult) && !design.pending;
|
|
61706
62033
|
if (!config2 || !view) {
|
|
61707
62034
|
const failed2 = experiment.status === "failed";
|
|
61708
62035
|
const noConfigs = !configsBind.error && configs.length === 0;
|
|
@@ -61770,7 +62097,7 @@ const EastChakraExperiment = memo(function EastChakraExperiment2({ value }) {
|
|
|
61770
62097
|
readonly && /* @__PURE__ */ jsx$1(Box, { as: "span", css: badge({ variant: "plain", size: "sm" }), textTransform: "none", letterSpacing: "normal", children: "View only" }),
|
|
61771
62098
|
/* @__PURE__ */ jsxs(Box, { as: "span", css: dataStatus.root, children: [
|
|
61772
62099
|
/* @__PURE__ */ jsx$1(Box, { as: "span", css: dataStatus.indicator }),
|
|
61773
|
-
/* @__PURE__ */ jsx$1(Box, { as: "span", css: dataStatus.label, children: stale ? `${nRows} rows` : vs.dataLabel })
|
|
62100
|
+
/* @__PURE__ */ jsx$1(Box, { as: "span", css: dataStatus.label, children: stale ? `${words.number(nRows)} rows` : vs.dataLabel })
|
|
61774
62101
|
] }),
|
|
61775
62102
|
/* @__PURE__ */ jsx$1(GuidanceToggle, { on: guidance, onToggle: () => setGuidance((g2) => !g2) }),
|
|
61776
62103
|
canRun && /* @__PURE__ */ jsx$1(ActionButton, { button, variant: "solid", label: "Run", onClick: onRun, disabled: runDisabled, pulse: stale }),
|
|
@@ -61803,7 +62130,7 @@ const EastChakraExperiment = memo(function EastChakraExperiment2({ value }) {
|
|
|
61803
62130
|
"add another"
|
|
61804
62131
|
] }) })
|
|
61805
62132
|
] }) }),
|
|
61806
|
-
/* @__PURE__ */ jsx$1(Step, { n: 4, title: `Which ${subject.many}?`, help: "step_population", children: /* @__PURE__ */ jsx$1(FilterRail, { fields, population, onChange: editPopulation, chip, button, readonly, subjectMany: subject.many }) }),
|
|
62133
|
+
/* @__PURE__ */ jsx$1(Step, { n: 4, title: `Which ${subject.many}?`, help: "step_population", children: /* @__PURE__ */ jsx$1(FilterRail, { fields, population, onChange: editPopulation, chip, button, readonly, subjectMany: subject.many, words }) }),
|
|
61807
62134
|
/* @__PURE__ */ jsxs(Box, { as: "details", borderTopWidth: "1px", borderColor: "border.subtle", children: [
|
|
61808
62135
|
/* @__PURE__ */ jsxs(
|
|
61809
62136
|
Box,
|
|
@@ -61921,10 +62248,11 @@ const EastChakraExperiment = memo(function EastChakraExperiment2({ value }) {
|
|
|
61921
62248
|
subjectMany: subject.many,
|
|
61922
62249
|
higherBetter,
|
|
61923
62250
|
badge,
|
|
61924
|
-
barList
|
|
62251
|
+
barList,
|
|
62252
|
+
words
|
|
61925
62253
|
}
|
|
61926
62254
|
),
|
|
61927
|
-
activeTab === "answer" && !a2 && ref && /* @__PURE__ */ jsx$1(RefusalZone, { refusal: ref, overlap: ov, naiveValue: (shownResult == null ? void 0 : shownResult.naive) ?? 0, outcome: vs.outcomeLabel }),
|
|
62255
|
+
activeTab === "answer" && !a2 && ref && /* @__PURE__ */ jsx$1(RefusalZone, { refusal: ref, overlap: ov, naiveValue: (shownResult == null ? void 0 : shownResult.naive) ?? 0, outcome: vs.outcomeLabel, words }),
|
|
61928
62256
|
activeTab === "trust" && vr && /* @__PURE__ */ jsxs(Box, { p: "4.5", children: [
|
|
61929
62257
|
/* @__PURE__ */ jsx$1(Text, { textStyle: "body.sm", color: "fg.muted", mb: "3.5", children: /* @__PURE__ */ jsx$1(Help, { id: "trust_intro", children: "Before trusting the answer we tried to break it — colour shows pass / caution." }) }),
|
|
61930
62258
|
/* @__PURE__ */ jsx$1(Box, { layerStyle: "frame.flat", children: vr.checks.map((c2, i) => {
|
|
@@ -61952,6 +62280,7 @@ const EastChakraExperiment = memo(function EastChakraExperiment2({ value }) {
|
|
|
61952
62280
|
zero: 0,
|
|
61953
62281
|
tone: "brand",
|
|
61954
62282
|
xTicks: vr.sens.xTicks,
|
|
62283
|
+
xTickWords: true,
|
|
61955
62284
|
yTicks: vr.sens.yTicks,
|
|
61956
62285
|
marks: vr.sens.marks,
|
|
61957
62286
|
height: vr.sens.marks.length ? 148 : 132
|
|
@@ -61997,13 +62326,13 @@ const EastChakraExperiment = memo(function EastChakraExperiment2({ value }) {
|
|
|
61997
62326
|
/* @__PURE__ */ jsxs(Box, { display: "flex", flexDirection: "column", gap: "0.5", children: [
|
|
61998
62327
|
/* @__PURE__ */ jsx$1(Text, { textStyle: "caption.eyebrow", children: vd.recoLabel }),
|
|
61999
62328
|
/* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "baseline", gap: "2", children: [
|
|
62000
|
-
/* @__PURE__ */ jsx$1(Text, { textStyle: "mono-kpi", fontFamily: "heading", color: "brand.solid", children: signed(vd.recoEffect) }),
|
|
62329
|
+
/* @__PURE__ */ jsx$1(Text, { textStyle: "mono-kpi", fontFamily: "heading", color: "brand.solid", children: signed(vd.recoEffect, words) }),
|
|
62001
62330
|
/* @__PURE__ */ jsxs(Text, { textStyle: "mono.sm", color: "fg.muted", children: [
|
|
62002
62331
|
vd.outcome,
|
|
62003
62332
|
" · ",
|
|
62004
|
-
signed(vd.recoLo),
|
|
62333
|
+
signed(vd.recoLo, words),
|
|
62005
62334
|
" … ",
|
|
62006
|
-
signed(vd.recoHi)
|
|
62335
|
+
signed(vd.recoHi, words)
|
|
62007
62336
|
] })
|
|
62008
62337
|
] })
|
|
62009
62338
|
] }),
|
|
@@ -62015,7 +62344,7 @@ const EastChakraExperiment = memo(function EastChakraExperiment2({ value }) {
|
|
|
62015
62344
|
vd.outcome,
|
|
62016
62345
|
" per step"
|
|
62017
62346
|
] }),
|
|
62018
|
-
/* @__PURE__ */ jsx$1(Box, { py: "0.5", maxH: "200px", overflowY: "auto", children: barList(vd.marginal.map((m2, i) => ({ label: m2.label, frac: m2.frac, tone: i < 2 ? "brand" : "muted", value: signed(m2.value) }))) })
|
|
62347
|
+
/* @__PURE__ */ jsx$1(Box, { py: "0.5", maxH: "200px", overflowY: "auto", children: barList(vd.marginal.map((m2, i) => ({ label: m2.label, frac: m2.frac, tone: i < 2 ? "brand" : "muted", value: signed(m2.value, words) }))) })
|
|
62019
62348
|
] })
|
|
62020
62349
|
] })
|
|
62021
62350
|
] }),
|
|
@@ -62033,7 +62362,7 @@ const EastChakraExperiment = memo(function EastChakraExperiment2({ value }) {
|
|
|
62033
62362
|
" tab for why)."
|
|
62034
62363
|
] })
|
|
62035
62364
|
] }),
|
|
62036
|
-
activeTab === "validate" && (design.status === "failed" && design.error ? /* @__PURE__ */ jsx$1(Box, { px: "4.5", pt: "4.5", children: /* @__PURE__ */ jsx$1(RunError, { error: design.error }) }) : designFresh && vmDesign ? /* @__PURE__ */ jsx$1(ValidatePanel, { vm: vmDesign, barList }) : !hasDesign && precomputedDesign === null ? /* @__PURE__ */ jsxs(Box, { p: "4.5", children: [
|
|
62365
|
+
activeTab === "validate" && (design.status === "failed" && design.error ? /* @__PURE__ */ jsx$1(Box, { px: "4.5", pt: "4.5", children: /* @__PURE__ */ jsx$1(RunError, { error: design.error }) }) : designFresh && vmDesign ? /* @__PURE__ */ jsx$1(ValidatePanel, { vm: vmDesign, barList, words }) : !hasDesign && precomputedDesign === null ? /* @__PURE__ */ jsxs(Box, { p: "4.5", children: [
|
|
62037
62366
|
/* @__PURE__ */ jsxs(Box, { display: "inline-flex", alignItems: "center", gap: "2", mb: "2", color: "fg.muted", children: [
|
|
62038
62367
|
/* @__PURE__ */ jsx$1(FontAwesomeIcon, { icon: faTriangleExclamation, style: { fontSize: "13px" } }),
|
|
62039
62368
|
/* @__PURE__ */ jsx$1(Text, { textStyle: "body.sm", fontWeight: "semibold", color: "fg.default", children: "No trial recipe for this question" })
|
|
@@ -62050,7 +62379,7 @@ const EastChakraExperiment = memo(function EastChakraExperiment2({ value }) {
|
|
|
62050
62379
|
/* @__PURE__ */ jsxs(Box, { css: es.root, bg: "bg.canvas", borderTopWidth: "1px", borderColor: "border.subtle", children: [
|
|
62051
62380
|
/* @__PURE__ */ jsx$1(Box, { css: es.lbl, children: /* @__PURE__ */ jsx$1(Help, { id: "journal", children: "Committed experiments" }) }),
|
|
62052
62381
|
/* @__PURE__ */ jsx$1(Box, { css: es.meta, children: /* @__PURE__ */ jsxs(Text, { as: "span", children: [
|
|
62053
|
-
/* @__PURE__ */ jsx$1(Text, { as: "span", color: "fg.default", fontWeight: "semibold", children: journal.length }),
|
|
62382
|
+
/* @__PURE__ */ jsx$1(Text, { as: "span", color: "fg.default", fontWeight: "semibold", children: words.number(journal.length) }),
|
|
62054
62383
|
" on record",
|
|
62055
62384
|
journal.length > 50 ? " · showing newest 50" : ""
|
|
62056
62385
|
] }) })
|
|
@@ -62092,7 +62421,7 @@ const EastChakraExperiment = memo(function EastChakraExperiment2({ value }) {
|
|
|
62092
62421
|
] })
|
|
62093
62422
|
] }) });
|
|
62094
62423
|
}, (prev2, next2) => experimentValueEqual(prev2.value, next2.value) && prev2.storageKey === next2.storageKey);
|
|
62095
|
-
function AnswerNumeric({ a: a2, verdict, narrative, checks, onGoTrust, subjectMany, higherBetter, badge, barList }) {
|
|
62424
|
+
function AnswerNumeric({ a: a2, verdict, narrative, checks, onGoTrust, subjectMany, higherBetter, badge, barList, words }) {
|
|
62096
62425
|
const dirUp = a2.effect > 0;
|
|
62097
62426
|
const statusWord = higherBetter === void 0 ? dirUp ? "Higher" : "Lower" : dirUp === higherBetter ? "Better" : "Worse";
|
|
62098
62427
|
const lowerWord = a2.naive < 0 ? "lower" : "higher";
|
|
@@ -62107,7 +62436,7 @@ function AnswerNumeric({ a: a2, verdict, narrative, checks, onGoTrust, subjectMa
|
|
|
62107
62436
|
/* @__PURE__ */ jsx$1(Text, { textStyle: "mono.sm", color: "fg.muted", children: a2.outcome }),
|
|
62108
62437
|
/* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "baseline", gap: "2.5", children: [
|
|
62109
62438
|
/* @__PURE__ */ jsx$1(Text, { textStyle: "mono-kpi", fontFamily: "heading", fontSize: "32px", color: kpiColor, children: /* @__PURE__ */ jsxs(Help, { id: "answer_effect", children: [
|
|
62110
|
-
signed(a2.effect),
|
|
62439
|
+
signed(a2.effect, words),
|
|
62111
62440
|
a2.unit ? /* @__PURE__ */ jsxs(Text, { as: "span", fontSize: "16px", color: "fg.muted", children: [
|
|
62112
62441
|
" ",
|
|
62113
62442
|
a2.unit
|
|
@@ -62115,9 +62444,9 @@ function AnswerNumeric({ a: a2, verdict, narrative, checks, onGoTrust, subjectMa
|
|
|
62115
62444
|
] }) }),
|
|
62116
62445
|
/* @__PURE__ */ jsx$1(Text, { textStyle: "mono.sm", color: "fg.muted", children: /* @__PURE__ */ jsxs(Help, { id: "answer_ci", children: [
|
|
62117
62446
|
"likely between ",
|
|
62118
|
-
signed(a2.lo),
|
|
62447
|
+
signed(a2.lo, words),
|
|
62119
62448
|
" and ",
|
|
62120
|
-
signed(a2.hi)
|
|
62449
|
+
signed(a2.hi, words)
|
|
62121
62450
|
] }) })
|
|
62122
62451
|
] })
|
|
62123
62452
|
] }),
|
|
@@ -62181,7 +62510,7 @@ function AnswerNumeric({ a: a2, verdict, narrative, checks, onGoTrust, subjectMa
|
|
|
62181
62510
|
" on ",
|
|
62182
62511
|
/* @__PURE__ */ jsx$1(Text, { as: "span", fontWeight: "semibold", children: a2.outcome }),
|
|
62183
62512
|
" (",
|
|
62184
|
-
signed(a2.naive),
|
|
62513
|
+
signed(a2.naive, words),
|
|
62185
62514
|
") — but they also differ most on ",
|
|
62186
62515
|
/* @__PURE__ */ jsx$1(Text, { as: "span", fontWeight: "semibold", children: top.label }),
|
|
62187
62516
|
" (",
|
|
@@ -62240,13 +62569,13 @@ function AnswerNumeric({ a: a2, verdict, narrative, checks, onGoTrust, subjectMa
|
|
|
62240
62569
|
/* @__PURE__ */ jsx$1(Box, { px: "3.5", pb: "3.5", py: "0.5", maxH: "208px", overflowY: "auto", children: barList(a2.balance.map((b2) => ({ label: b2.label, frac: b2.frac, tone: b2.tone, value: b2.display }))) })
|
|
62241
62570
|
] }),
|
|
62242
62571
|
/* @__PURE__ */ jsx$1(Box, { mt: "3.5", children: /* @__PURE__ */ jsx$1(Help, { id: "counts", display: "inline-flex", gap: "4", children: [[a2.nTotal, subjectMany], [a2.nCompared, "compared like-for-like"], [a2.nDropped, "had no fair match"]].map(([n2, label], i) => /* @__PURE__ */ jsxs(Text, { textStyle: "mono.sm", color: "fg.muted", children: [
|
|
62243
|
-
/* @__PURE__ */ jsx$1(Text, { as: "span", color: "fg.default", fontWeight: "semibold", children:
|
|
62572
|
+
/* @__PURE__ */ jsx$1(Text, { as: "span", color: "fg.default", fontWeight: "semibold", children: words.number(n2) }),
|
|
62244
62573
|
" ",
|
|
62245
62574
|
label
|
|
62246
62575
|
] }, i)) }) })
|
|
62247
62576
|
] });
|
|
62248
62577
|
}
|
|
62249
|
-
function RefusalZone({ refusal, overlap, naiveValue, outcome }) {
|
|
62578
|
+
function RefusalZone({ refusal, overlap, naiveValue, outcome, words }) {
|
|
62250
62579
|
return /* @__PURE__ */ jsxs(Box, { p: "4.5", children: [
|
|
62251
62580
|
/* @__PURE__ */ jsxs(Box, { display: "inline-flex", alignItems: "center", gap: "2", mb: "2", color: "fg.warning", children: [
|
|
62252
62581
|
/* @__PURE__ */ jsx$1(FontAwesomeIcon, { icon: faTriangleExclamation, style: { fontSize: "14px" } }),
|
|
@@ -62269,11 +62598,11 @@ function RefusalZone({ refusal, overlap, naiveValue, outcome }) {
|
|
|
62269
62598
|
"Raw average difference in ",
|
|
62270
62599
|
outcome,
|
|
62271
62600
|
" (context only, not an answer): ",
|
|
62272
|
-
/* @__PURE__ */ jsx$1(Text, { as: "span", fontFamily: "mono", color: "fg.muted", children: signed(naiveValue) })
|
|
62601
|
+
/* @__PURE__ */ jsx$1(Text, { as: "span", fontFamily: "mono", color: "fg.muted", children: signed(naiveValue, words) })
|
|
62273
62602
|
] })
|
|
62274
62603
|
] });
|
|
62275
62604
|
}
|
|
62276
|
-
function ValidatePanel({ vm, barList }) {
|
|
62605
|
+
function ValidatePanel({ vm, barList, words }) {
|
|
62277
62606
|
const stat = useSlotRecipe({ key: "stat" })({ size: "lg" });
|
|
62278
62607
|
const meter = useSlotRecipe({ key: "segmentedMeter" })({});
|
|
62279
62608
|
return /* @__PURE__ */ jsxs(Box, { p: "4.5", children: [
|
|
@@ -62281,7 +62610,7 @@ function ValidatePanel({ vm, barList }) {
|
|
|
62281
62610
|
/* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "flex-end", gap: "5", flexWrap: "wrap", children: [
|
|
62282
62611
|
/* @__PURE__ */ jsxs(Box, { css: stat.root, children: [
|
|
62283
62612
|
/* @__PURE__ */ jsx$1(Text, { css: stat.label, children: /* @__PURE__ */ jsx$1(Help, { id: "validate_size", children: vm.holdback ? "to hold back from" : "to run" }) }),
|
|
62284
|
-
vm.faint ? /* @__PURE__ */ jsx$1(Text, { textStyle: "body.sm", fontWeight: "semibold", color: "fg.warning", maxW: "220px", children: "Effect too faint to size — set a materiality threshold to size a trial." }) : /* @__PURE__ */ jsx$1(Text, { css: stat.valueText, color: "brand.solid", children: vm.primary.nTotal
|
|
62613
|
+
vm.faint ? /* @__PURE__ */ jsx$1(Text, { textStyle: "body.sm", fontWeight: "semibold", color: "fg.warning", maxW: "220px", children: "Effect too faint to size — set a materiality threshold to size a trial." }) : /* @__PURE__ */ jsx$1(Text, { css: stat.valueText, color: "brand.solid", children: words.number(vm.primary.nTotal) })
|
|
62285
62614
|
] }),
|
|
62286
62615
|
/* @__PURE__ */ jsxs(Box, { css: meter.root, flex: "1", minW: "220px", children: [
|
|
62287
62616
|
/* @__PURE__ */ jsx$1(Text, { css: meter.label, children: /* @__PURE__ */ jsx$1(Help, { id: "validate_split", children: vm.holdback ? "Hold-back split" : "Split" }) }),
|
|
@@ -62293,7 +62622,7 @@ function ValidatePanel({ vm, barList }) {
|
|
|
62293
62622
|
/* @__PURE__ */ jsxs(Box, { css: meter.keyItem, children: [
|
|
62294
62623
|
/* @__PURE__ */ jsx$1(Box, { css: meter.keyDot, bg: "brand.solid" }),
|
|
62295
62624
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
62296
|
-
/* @__PURE__ */ jsx$1(Text, { as: "span", css: meter.valueText, children: vm.primary.nTreated
|
|
62625
|
+
/* @__PURE__ */ jsx$1(Text, { as: "span", css: meter.valueText, children: words.number(vm.primary.nTreated) }),
|
|
62297
62626
|
" ",
|
|
62298
62627
|
vm.holdback ? "treated" : "get it"
|
|
62299
62628
|
] })
|
|
@@ -62301,7 +62630,7 @@ function ValidatePanel({ vm, barList }) {
|
|
|
62301
62630
|
/* @__PURE__ */ jsxs(Box, { css: meter.keyItem, children: [
|
|
62302
62631
|
/* @__PURE__ */ jsx$1(Box, { css: meter.keyDot, bg: "bg.emphasized" }),
|
|
62303
62632
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
62304
|
-
/* @__PURE__ */ jsx$1(Text, { as: "span", css: meter.valueText, children: vm.primary.nControl
|
|
62633
|
+
/* @__PURE__ */ jsx$1(Text, { as: "span", css: meter.valueText, children: words.number(vm.primary.nControl) }),
|
|
62305
62634
|
" ",
|
|
62306
62635
|
vm.holdback ? "held back" : "left alone"
|
|
62307
62636
|
] })
|
|
@@ -62334,16 +62663,16 @@ function ValidatePanel({ vm, barList }) {
|
|
|
62334
62663
|
vm.alternates.length > 0 && /* @__PURE__ */ jsx$1(Box, { display: "flex", flexDirection: "column", gap: "1.5", mt: "3", pt: "3", borderTopWidth: "1px", borderColor: "border.subtle", children: vm.alternates.map((o2, i) => /* @__PURE__ */ jsxs(Text, { textStyle: "caption", color: "fg.muted", children: [
|
|
62335
62664
|
/* @__PURE__ */ jsx$1(Text, { as: "span", fontWeight: "semibold", color: "fg.default", children: o2.label }),
|
|
62336
62665
|
" · ",
|
|
62337
|
-
o2.nTotal
|
|
62666
|
+
words.number(o2.nTotal),
|
|
62338
62667
|
" total (",
|
|
62339
|
-
o2.nTreated
|
|
62668
|
+
words.number(o2.nTreated),
|
|
62340
62669
|
" / ",
|
|
62341
|
-
o2.nControl
|
|
62670
|
+
words.number(o2.nControl),
|
|
62342
62671
|
")"
|
|
62343
62672
|
] }, i)) })
|
|
62344
62673
|
] });
|
|
62345
62674
|
}
|
|
62346
|
-
function FilterRail({ fields, population, onChange: onChange2, chip, button, readonly, subjectMany }) {
|
|
62675
|
+
function FilterRail({ fields, population, onChange: onChange2, chip, button, readonly, subjectMany, words }) {
|
|
62347
62676
|
const [open, setOpen] = useState(null);
|
|
62348
62677
|
const replaceAt = (i, p2) => onChange2(population.map((f2, j2) => j2 === i ? p2 : f2));
|
|
62349
62678
|
const removeAt = (i) => onChange2(population.filter((_2, j2) => j2 !== i));
|
|
@@ -62352,7 +62681,7 @@ function FilterRail({ fields, population, onChange: onChange2, chip, button, rea
|
|
|
62352
62681
|
return /* @__PURE__ */ jsx$1(Box, { display: "flex", flexWrap: "wrap", gap: "1.5", alignItems: "center", children: population.length === 0 ? /* @__PURE__ */ jsxs(Box, { css: chip({ tone: "plain", numeric: true, shape: "rounded" }), children: [
|
|
62353
62682
|
"all ",
|
|
62354
62683
|
subjectMany
|
|
62355
|
-
] }) : population.map((pred, i) => /* @__PURE__ */ jsx$1(Box, { css: chip({ tone: "brand", numeric: true, shape: "rounded" }), flexShrink: 0, children: /* @__PURE__ */ jsx$1(Box, { as: "span", whiteSpace: "nowrap", children: formatPredicate(pred) }) }, i)) });
|
|
62684
|
+
] }) : population.map((pred, i) => /* @__PURE__ */ jsx$1(Box, { css: chip({ tone: "brand", numeric: true, shape: "rounded" }), flexShrink: 0, children: /* @__PURE__ */ jsx$1(Box, { as: "span", whiteSpace: "nowrap", children: formatPredicate(pred, words) }) }, i)) });
|
|
62356
62685
|
}
|
|
62357
62686
|
return /* @__PURE__ */ jsxs(Box, { display: "flex", flexWrap: "wrap", gap: "1.5", alignItems: "center", children: [
|
|
62358
62687
|
population.map((pred, i) => /* @__PURE__ */ jsx$1(
|
|
@@ -62366,7 +62695,7 @@ function FilterRail({ fields, population, onChange: onChange2, chip, button, rea
|
|
|
62366
62695
|
] }),
|
|
62367
62696
|
footActions: done,
|
|
62368
62697
|
trigger: /* @__PURE__ */ jsxs(Box, { css: chip({ tone: "brand", numeric: true, shape: "rounded" }), cursor: "pointer", flexShrink: 0, children: [
|
|
62369
|
-
/* @__PURE__ */ jsx$1(Box, { as: "span", whiteSpace: "nowrap", children: formatPredicate(pred) }),
|
|
62698
|
+
/* @__PURE__ */ jsx$1(Box, { as: "span", whiteSpace: "nowrap", children: formatPredicate(pred, words) }),
|
|
62370
62699
|
/* @__PURE__ */ jsx$1(Box, { as: "button", display: "inline-flex", alignItems: "center", cursor: "pointer", color: "brand.fg", flexShrink: "0", fontSize: "10px", onClick: (e3) => {
|
|
62371
62700
|
e3.stopPropagation();
|
|
62372
62701
|
removeAt(i);
|
|
@@ -62492,20 +62821,8 @@ function viewFor(binding) {
|
|
|
62492
62821
|
const patch = binding.patch.type === "some" ? binding.patch.value : void 0;
|
|
62493
62822
|
return defaultBindRuntime.buildBindHandle(types.sourceType, source, patch, binding.mode.type);
|
|
62494
62823
|
}
|
|
62495
|
-
|
|
62496
|
-
|
|
62497
|
-
if (typeof x2 === "bigint") return `${x2}n`;
|
|
62498
|
-
if (x2 instanceof Date) return x2.toISOString();
|
|
62499
|
-
if (isEastSet(x2)) return [...x2].sort();
|
|
62500
|
-
if (isEastDict(x2)) return [...x2.entries()].sort((a2, b2) => String(a2[0]).localeCompare(String(b2[0])));
|
|
62501
|
-
return x2;
|
|
62502
|
-
});
|
|
62503
|
-
}
|
|
62504
|
-
function hashString2(s2) {
|
|
62505
|
-
let h2 = 5381;
|
|
62506
|
-
for (let i = 0; i < s2.length; i++) h2 = (h2 << 5) + h2 + s2.charCodeAt(i) | 0;
|
|
62507
|
-
return (h2 >>> 0).toString(36);
|
|
62508
|
-
}
|
|
62824
|
+
const printDescriptors = printFor(StructType({ decisions: ArrayType(DiffBindingType), judgements: DiffBindingType }));
|
|
62825
|
+
const printTypeValue = printFor(EastTypeValueType);
|
|
62509
62826
|
function readSelectionAt(selectionKey) {
|
|
62510
62827
|
StateRuntime.trackKey(selectionKey);
|
|
62511
62828
|
const bytes = StateRuntime.getStore().read(selectionKey);
|
|
@@ -62547,16 +62864,6 @@ function removeFromOwningView(decisions, caseId) {
|
|
|
62547
62864
|
}
|
|
62548
62865
|
}
|
|
62549
62866
|
const decisionHandleCache = /* @__PURE__ */ new Map();
|
|
62550
|
-
function typeToken(tv) {
|
|
62551
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
62552
|
-
return JSON.stringify(tv, (_k, v3) => {
|
|
62553
|
-
if (typeof v3 === "object" && v3 !== null) {
|
|
62554
|
-
if (seen.has(v3)) return "<cyc>";
|
|
62555
|
-
seen.add(v3);
|
|
62556
|
-
}
|
|
62557
|
-
return typeof v3 === "bigint" ? `${v3}n` : v3;
|
|
62558
|
-
});
|
|
62559
|
-
}
|
|
62560
62867
|
function compileDecisionMethods(constraintType, decisions, judgements, selectionKey) {
|
|
62561
62868
|
const platform = getRegisteredPlatformImplementations();
|
|
62562
62869
|
const c2 = fromEastTypeValue(constraintType);
|
|
@@ -62624,7 +62931,7 @@ function buildDecisionHandle(decisions, judgements, constraintType) {
|
|
|
62624
62931
|
const at = (j2) => j2.resolvedAt.type === "some" ? j2.resolvedAt.value.getTime() : 0;
|
|
62625
62932
|
return entries.sort((a2, b2) => at(b2) - at(a2));
|
|
62626
62933
|
};
|
|
62627
|
-
const cacheKey = `${
|
|
62934
|
+
const cacheKey = `${printDescriptors({ decisions, judgements })}|${printTypeValue(canonicalTypeValue(cType))}`;
|
|
62628
62935
|
let methods = decisionHandleCache.get(cacheKey);
|
|
62629
62936
|
if (methods === void 0) {
|
|
62630
62937
|
methods = compileDecisionMethods(cType, decisions, judgements, selectionKey);
|
|
@@ -62814,91 +63121,71 @@ const OP_WORDS = {
|
|
|
62814
63121
|
notIn: "not in",
|
|
62815
63122
|
is: "is"
|
|
62816
63123
|
};
|
|
62817
|
-
|
|
62818
|
-
|
|
62819
|
-
|
|
62820
|
-
|
|
62821
|
-
|
|
62822
|
-
|
|
63124
|
+
const PRINTERS = /* @__PURE__ */ new WeakMap();
|
|
63125
|
+
function printerOf(contract) {
|
|
63126
|
+
let printer = PRINTERS.get(contract);
|
|
63127
|
+
if (printer === void 0) {
|
|
63128
|
+
const context = /* @__PURE__ */ new Map();
|
|
63129
|
+
printFor(contract.type, context);
|
|
63130
|
+
printer = (type) => printFor(type, context);
|
|
63131
|
+
PRINTERS.set(contract, printer);
|
|
62823
63132
|
}
|
|
62824
|
-
|
|
62825
|
-
return Object.entries(v3).map(([k2, x2]) => `${k2} ${formatScalar(x2)}`).join(" · ");
|
|
62826
|
-
}
|
|
62827
|
-
return String(v3);
|
|
63133
|
+
return printer;
|
|
62828
63134
|
}
|
|
62829
|
-
function
|
|
62830
|
-
|
|
62831
|
-
|
|
62832
|
-
|
|
62833
|
-
|
|
62834
|
-
|
|
62835
|
-
|
|
62836
|
-
|
|
62837
|
-
|
|
62838
|
-
const
|
|
62839
|
-
|
|
62840
|
-
return { lever, op: word, value: `${formatScalar(r2.min)} – ${formatScalar(r2.max)}` };
|
|
62841
|
-
}
|
|
63135
|
+
function formatValue(value, type, words, print) {
|
|
63136
|
+
switch (type.type) {
|
|
63137
|
+
case "DateTime":
|
|
63138
|
+
return words.monthDay(value);
|
|
63139
|
+
case "Float":
|
|
63140
|
+
return words.float(value);
|
|
63141
|
+
case "String":
|
|
63142
|
+
return value;
|
|
63143
|
+
case "Set": {
|
|
63144
|
+
const member = type.value;
|
|
63145
|
+
return `{${[...value].map((m2) => formatValue(m2, member, words, print)).join(", ")}}`;
|
|
62842
63146
|
}
|
|
62843
|
-
return { lever, op: word, value: formatScalar(op.value) };
|
|
62844
|
-
}
|
|
62845
|
-
return { lever, op: "·", value: formatScalar(c2.value) };
|
|
62846
|
-
}
|
|
62847
|
-
const PRIMITIVES = /* @__PURE__ */ new Set(["String", "Integer", "Float", "DateTime", "Boolean"]);
|
|
62848
|
-
function normalizeTypeValue(tv) {
|
|
62849
|
-
var _a2;
|
|
62850
|
-
const n2 = tv;
|
|
62851
|
-
if (n2.cases !== void 0 || n2.fields !== void 0) {
|
|
62852
|
-
const out = { type: n2.type };
|
|
62853
|
-
if (n2.cases) out.cases = Object.fromEntries(Object.entries(n2.cases).map(([k2, v3]) => [k2, normalizeTypeValue(v3)]));
|
|
62854
|
-
if (n2.fields) out.fields = Object.fromEntries(Object.entries(n2.fields).map(([k2, v3]) => [k2, normalizeTypeValue(v3)]));
|
|
62855
|
-
if (n2.key) out.key = normalizeTypeValue(n2.key);
|
|
62856
|
-
if (n2.value !== void 0 && (n2.type === "Array" || n2.type === "Dict")) out.value = normalizeTypeValue(n2.value);
|
|
62857
|
-
return out;
|
|
62858
|
-
}
|
|
62859
|
-
switch (n2.type) {
|
|
62860
63147
|
case "Struct":
|
|
62861
|
-
return
|
|
62862
|
-
case "Variant":
|
|
62863
|
-
return { type: "Variant", cases: Object.fromEntries(n2.value.map((f2) => [f2.name, normalizeTypeValue(f2.type)])) };
|
|
62864
|
-
case "Array":
|
|
62865
|
-
return { type: "Array", value: normalizeTypeValue(n2.value) };
|
|
62866
|
-
case "Dict": {
|
|
62867
|
-
const d2 = n2.value;
|
|
62868
|
-
return { type: "Dict", key: normalizeTypeValue(d2.key), value: normalizeTypeValue(d2.value) };
|
|
62869
|
-
}
|
|
62870
|
-
case "Recursive": {
|
|
62871
|
-
const w2 = n2.value;
|
|
62872
|
-
if ((w2 == null ? void 0 : w2.type) === "wrapper" && ((_a2 = w2.value) == null ? void 0 : _a2.inner)) return normalizeTypeValue(w2.value.inner);
|
|
62873
|
-
return { type: n2.type };
|
|
62874
|
-
}
|
|
63148
|
+
return type.value.map((f2) => `${f2.name} ${formatValue(value[f2.name], f2.type, words, print)}`).join(" · ");
|
|
62875
63149
|
default:
|
|
62876
|
-
return
|
|
63150
|
+
return print(type)(value);
|
|
62877
63151
|
}
|
|
62878
63152
|
}
|
|
62879
|
-
function
|
|
62880
|
-
|
|
62881
|
-
|
|
62882
|
-
|
|
62883
|
-
|
|
62884
|
-
|
|
62885
|
-
|
|
62886
|
-
|
|
62887
|
-
|
|
62888
|
-
|
|
62889
|
-
|
|
62890
|
-
|
|
62891
|
-
|
|
62892
|
-
|
|
62893
|
-
|
|
62894
|
-
|
|
63153
|
+
function formatConstraint(constraint, contract, levers, words = formatters()) {
|
|
63154
|
+
var _a2;
|
|
63155
|
+
const lever = ((_a2 = levers == null ? void 0 : levers.find((l2) => l2.case === constraint.type)) == null ? void 0 : _a2.label) ?? constraint.type;
|
|
63156
|
+
const payload = contract == null ? void 0 : contract.payloads.get(constraint.type);
|
|
63157
|
+
if (contract === void 0 || payload === void 0) return { lever, op: "·", value: "" };
|
|
63158
|
+
const print = printerOf(contract);
|
|
63159
|
+
if (payload.type === "Variant") {
|
|
63160
|
+
const op = constraint.value;
|
|
63161
|
+
const word = OP_WORDS[op.type] ?? op.type;
|
|
63162
|
+
const opType = payload.value.find((c2) => c2.name === op.type).type;
|
|
63163
|
+
if (opType.type === "Struct") {
|
|
63164
|
+
const fields = opType.value;
|
|
63165
|
+
const min4 = fields.find((f2) => f2.name === "min");
|
|
63166
|
+
const max5 = fields.find((f2) => f2.name === "max");
|
|
63167
|
+
if (min4 !== void 0 && max5 !== void 0) {
|
|
63168
|
+
const range = op.value;
|
|
63169
|
+
return { lever, op: word, value: `${formatValue(range.min, min4.type, words, print)} – ${formatValue(range.max, max5.type, words, print)}` };
|
|
63170
|
+
}
|
|
63171
|
+
}
|
|
63172
|
+
return { lever, op: word, value: formatValue(op.value, opType, words, print) };
|
|
62895
63173
|
}
|
|
63174
|
+
return { lever, op: "·", value: formatValue(constraint.value, payload, words, print) };
|
|
62896
63175
|
}
|
|
62897
|
-
|
|
62898
|
-
|
|
62899
|
-
|
|
62900
|
-
if (
|
|
62901
|
-
if (
|
|
63176
|
+
const PRIMITIVES = /* @__PURE__ */ new Set(["String", "Integer", "Float", "DateTime", "Boolean"]);
|
|
63177
|
+
const NULL_TYPE = toEastTypeValue(NullType);
|
|
63178
|
+
function emptyFor(type) {
|
|
63179
|
+
if (type.type === "DateTime") return /* @__PURE__ */ new Date();
|
|
63180
|
+
if (type.type === "Struct") return Object.fromEntries(type.value.map((f2) => [f2.name, emptyFor(f2.type)]));
|
|
63181
|
+
return defaultValue(type);
|
|
63182
|
+
}
|
|
63183
|
+
function leverPayloadEditable(payload) {
|
|
63184
|
+
if (payload === void 0) return false;
|
|
63185
|
+
const primitive = (t4) => PRIMITIVES.has(t4.type);
|
|
63186
|
+
const structOfPrimitives = (t4) => t4.type === "Struct" && t4.value.every((f2) => primitive(f2.type));
|
|
63187
|
+
if (primitive(payload) || structOfPrimitives(payload)) return true;
|
|
63188
|
+
if (payload.type === "Variant") return payload.value.every((c2) => primitive(c2.type) || structOfPrimitives(c2.type));
|
|
62902
63189
|
return false;
|
|
62903
63190
|
}
|
|
62904
63191
|
const inputStyle = some({ size: some(variant("sm", null)) });
|
|
@@ -62906,17 +63193,17 @@ function LeverEditor({ leverCase, payload, onInject }) {
|
|
|
62906
63193
|
var _a2;
|
|
62907
63194
|
const button = useRecipe({ key: "button" });
|
|
62908
63195
|
const isOpVariant = payload.type === "Variant";
|
|
62909
|
-
const ops = useMemo(() =>
|
|
63196
|
+
const ops = useMemo(() => payload.type === "Variant" ? payload.value.map((c2) => c2.name) : [], [payload]);
|
|
62910
63197
|
const [opTag, setOpTag] = useState(ops[0] ?? "");
|
|
62911
|
-
const active =
|
|
63198
|
+
const active = payload.type === "Variant" ? ((_a2 = payload.value.find((c2) => c2.name === opTag)) == null ? void 0 : _a2.type) ?? NULL_TYPE : payload;
|
|
62912
63199
|
const valRef = useRef(emptyFor(active));
|
|
62913
63200
|
const keyRef = useRef(`${leverCase}:${opTag}`);
|
|
62914
63201
|
if (keyRef.current !== `${leverCase}:${opTag}`) {
|
|
62915
63202
|
keyRef.current = `${leverCase}:${opTag}`;
|
|
62916
63203
|
valRef.current = emptyFor(active);
|
|
62917
63204
|
}
|
|
62918
|
-
const primitiveInput = (
|
|
62919
|
-
switch (
|
|
63205
|
+
const primitiveInput = (type, key, get3, set3) => {
|
|
63206
|
+
switch (type.type) {
|
|
62920
63207
|
case "Integer":
|
|
62921
63208
|
return /* @__PURE__ */ jsx$1(EastChakraIntegerInput, { value: { value: get3(), onChange: some(set3), style: inputStyle } }, key);
|
|
62922
63209
|
case "Float":
|
|
@@ -62929,7 +63216,7 @@ function LeverEditor({ leverCase, payload, onInject }) {
|
|
|
62929
63216
|
{
|
|
62930
63217
|
ariaLabel: key,
|
|
62931
63218
|
value: {
|
|
62932
|
-
value: some(
|
|
63219
|
+
value: some(get3() === true ? "true" : "false"),
|
|
62933
63220
|
items: [{ value: "true", label: "true", disabled: none$1 }, { value: "false", label: "false", disabled: none$1 }],
|
|
62934
63221
|
placeholder: none$1,
|
|
62935
63222
|
multiple: none$1,
|
|
@@ -62942,17 +63229,19 @@ function LeverEditor({ leverCase, payload, onInject }) {
|
|
|
62942
63229
|
},
|
|
62943
63230
|
key
|
|
62944
63231
|
);
|
|
63232
|
+
case "String":
|
|
63233
|
+
return /* @__PURE__ */ jsx$1(EastChakraStringInput, { value: { value: get3(), onChange: some(set3), style: inputStyle } }, key);
|
|
62945
63234
|
default:
|
|
62946
|
-
return
|
|
63235
|
+
return null;
|
|
62947
63236
|
}
|
|
62948
63237
|
};
|
|
62949
63238
|
const valueControls = useMemo(() => {
|
|
62950
63239
|
const k2 = keyRef.current;
|
|
62951
63240
|
if (active.type === "Struct") {
|
|
62952
|
-
return
|
|
63241
|
+
return active.value.map(({ name: field, type }) => /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", gap: "6px", minW: 0, children: [
|
|
62953
63242
|
/* @__PURE__ */ jsx$1(Box, { as: "span", textStyle: "caption.eyebrow", color: "fg.subtle", flexShrink: 0, children: field }),
|
|
62954
63243
|
primitiveInput(
|
|
62955
|
-
|
|
63244
|
+
type,
|
|
62956
63245
|
`${k2}.${field}.in`,
|
|
62957
63246
|
() => valRef.current[field],
|
|
62958
63247
|
(v3) => {
|
|
@@ -63008,11 +63297,12 @@ function LeverEditor({ leverCase, payload, onInject }) {
|
|
|
63008
63297
|
}
|
|
63009
63298
|
);
|
|
63010
63299
|
}
|
|
63011
|
-
function fmt(d2, n2, showSign = false) {
|
|
63012
|
-
return
|
|
63300
|
+
function fmt(words, d2, n2, showSign = false) {
|
|
63301
|
+
return words.value(n2, getSomeorUndefined(d2.format), showSign);
|
|
63013
63302
|
}
|
|
63014
63303
|
const caption = { textStyle: "caption.eyebrow", color: "fg.muted" };
|
|
63015
63304
|
const EvidenceFacet = memo(function EvidenceFacet2({ decision, children: children2 }) {
|
|
63305
|
+
const words = useFormatters();
|
|
63016
63306
|
const stakes = getSomeorUndefined(decision.stakes);
|
|
63017
63307
|
const downside = getSomeorUndefined(decision.downside);
|
|
63018
63308
|
const confidence = getSomeorUndefined(decision.confidence);
|
|
@@ -63028,15 +63318,12 @@ const EvidenceFacet = memo(function EvidenceFacet2({ decision, children: childre
|
|
|
63028
63318
|
] }),
|
|
63029
63319
|
downside !== void 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63030
63320
|
"if wrong ",
|
|
63031
|
-
/* @__PURE__ */ jsx$1(Text, { as: "span", fontFamily: "mono", fontWeight: "semibold", color: "fg.danger", children: fmt(decision, downside, true) }),
|
|
63321
|
+
/* @__PURE__ */ jsx$1(Text, { as: "span", fontFamily: "mono", fontWeight: "semibold", color: "fg.danger", children: fmt(words, decision, downside, true) }),
|
|
63032
63322
|
" · "
|
|
63033
63323
|
] }),
|
|
63034
63324
|
confidence !== void 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63035
63325
|
"confidence ",
|
|
63036
|
-
/* @__PURE__ */
|
|
63037
|
-
Math.round(confidence * 100),
|
|
63038
|
-
"%"
|
|
63039
|
-
] })
|
|
63326
|
+
/* @__PURE__ */ jsx$1(Text, { as: "span", fontFamily: "mono", fontWeight: "semibold", children: words.percent(confidence) })
|
|
63040
63327
|
] })
|
|
63041
63328
|
] })
|
|
63042
63329
|
] }),
|
|
@@ -63052,8 +63339,9 @@ const EvidenceFacet = memo(function EvidenceFacet2({ decision, children: childre
|
|
|
63052
63339
|
children2
|
|
63053
63340
|
] });
|
|
63054
63341
|
});
|
|
63342
|
+
const compareValues$1 = compareFor(FloatType);
|
|
63055
63343
|
function rankOptions(d2) {
|
|
63056
|
-
const alternatives = [...d2.alternatives].sort((a2, b2) => b2.value
|
|
63344
|
+
const alternatives = [...d2.alternatives].sort((a2, b2) => compareValues$1(b2.value, a2.value)).map((a2) => ({
|
|
63057
63345
|
label: a2.label,
|
|
63058
63346
|
value: a2.value,
|
|
63059
63347
|
downside: getSomeorUndefined(a2.downside),
|
|
@@ -63073,14 +63361,15 @@ function rankOptions(d2) {
|
|
|
63073
63361
|
...alternatives
|
|
63074
63362
|
].map((o2, i) => ({ ...o2, rank: i + 1 }));
|
|
63075
63363
|
}
|
|
63076
|
-
function metaLine(o2) {
|
|
63364
|
+
function metaLine(o2, words) {
|
|
63077
63365
|
const parts = [];
|
|
63078
63366
|
if (o2.recommended) parts.push("recommended");
|
|
63079
|
-
if (o2.confidence !== void 0) parts.push(`${
|
|
63367
|
+
if (o2.confidence !== void 0) parts.push(`${words.percent(o2.confidence)} conf`);
|
|
63080
63368
|
if (!o2.recommended && o2.note !== void 0) parts.push(o2.note);
|
|
63081
63369
|
return parts.join(" · ");
|
|
63082
63370
|
}
|
|
63083
63371
|
const OptionsFacet = memo(function OptionsFacet2({ decision, narrow }) {
|
|
63372
|
+
const words = useFormatters();
|
|
63084
63373
|
const options2 = rankOptions(decision);
|
|
63085
63374
|
const maxUp = Math.max(...options2.map((o2) => Math.max(o2.value, 0)), 1e-9);
|
|
63086
63375
|
const maxDown = Math.max(...options2.map((o2) => Math.abs(o2.downside ?? 0)), 1e-9);
|
|
@@ -63096,7 +63385,7 @@ const OptionsFacet = memo(function OptionsFacet2({ decision, narrow }) {
|
|
|
63096
63385
|
return /* @__PURE__ */ jsxs(Box, { display: "flex", flexDirection: "column", gap: "10px", children: [
|
|
63097
63386
|
/* @__PURE__ */ jsxs(Text, { ...caption, color: "fg", children: [
|
|
63098
63387
|
"Options · ",
|
|
63099
|
-
options2.length,
|
|
63388
|
+
words.number(options2.length),
|
|
63100
63389
|
" evaluated"
|
|
63101
63390
|
] }),
|
|
63102
63391
|
options2.map((o2) => /* @__PURE__ */ jsxs(Box, { display: "flex", flexDirection: "column", gap: "4px", pl: "8px", ...o2.recommended ? { boxShadow: "inset 2px 0 0 var(--chakra-colors-accent-brand)" } : {}, children: [
|
|
@@ -63105,8 +63394,8 @@ const OptionsFacet = memo(function OptionsFacet2({ decision, narrow }) {
|
|
|
63105
63394
|
" ",
|
|
63106
63395
|
/* @__PURE__ */ jsx$1(Text, { as: "span", fontWeight: o2.recommended ? "semibold" : "normal", children: o2.label })
|
|
63107
63396
|
] }),
|
|
63108
|
-
meter(upLabel, o2.value / maxUp, fmt(decision, o2.value, signed2), signed2 ? "success" : "neutral"),
|
|
63109
|
-
meter("If wrong", (o2.downside ?? 0) / maxDown, o2.downside !== void 0 ? fmt(decision, o2.downside, true) : "—", "danger")
|
|
63397
|
+
meter(upLabel, o2.value / maxUp, fmt(words, decision, o2.value, signed2), signed2 ? "success" : "neutral"),
|
|
63398
|
+
meter("If wrong", (o2.downside ?? 0) / maxDown, o2.downside !== void 0 ? fmt(words, decision, o2.downside, true) : "—", "danger")
|
|
63110
63399
|
] }, o2.rank))
|
|
63111
63400
|
] });
|
|
63112
63401
|
}
|
|
@@ -63114,7 +63403,7 @@ const OptionsFacet = memo(function OptionsFacet2({ decision, narrow }) {
|
|
|
63114
63403
|
/* @__PURE__ */ jsxs(Box, { display: "grid", gridTemplateColumns: "minmax(180px, 1.1fr) 1fr 1fr", alignItems: "baseline", gap: "8px", children: [
|
|
63115
63404
|
/* @__PURE__ */ jsxs(Text, { ...caption, color: "fg", children: [
|
|
63116
63405
|
"Options · ",
|
|
63117
|
-
options2.length,
|
|
63406
|
+
words.number(options2.length),
|
|
63118
63407
|
" evaluated"
|
|
63119
63408
|
] }),
|
|
63120
63409
|
/* @__PURE__ */ jsx$1(Text, { ...caption, textAlign: "center", children: "If wrong" }),
|
|
@@ -63136,15 +63425,15 @@ const OptionsFacet = memo(function OptionsFacet2({ decision, narrow }) {
|
|
|
63136
63425
|
/* @__PURE__ */ jsxs(Box, { minW: 0, pl: o2.recommended ? "6px" : "0", display: "flex", alignItems: "baseline", gap: "6px", children: [
|
|
63137
63426
|
/* @__PURE__ */ jsx$1(Text, { as: "span", fontFamily: "mono", fontSize: "11px", color: "fg.subtle", flexShrink: 0, children: o2.rank }),
|
|
63138
63427
|
/* @__PURE__ */ jsx$1(Text, { as: "span", fontSize: "12.5px", fontWeight: o2.recommended ? "semibold" : "normal", flexShrink: 0, children: o2.label }),
|
|
63139
|
-
metaLine(o2) !== "" && /* @__PURE__ */ jsx$1(Text, { as: "span", fontFamily: "mono", fontSize: "10.5px", color: "fg.muted", minW: 0, truncate: true, children: metaLine(o2) })
|
|
63428
|
+
metaLine(o2, words) !== "" && /* @__PURE__ */ jsx$1(Text, { as: "span", fontFamily: "mono", fontSize: "10.5px", color: "fg.muted", minW: 0, truncate: true, children: metaLine(o2, words) })
|
|
63140
63429
|
] }),
|
|
63141
63430
|
/* @__PURE__ */ jsx$1(Box, { display: "flex", justifyContent: "flex-end", alignItems: "center", gap: "6px", height: "16px", children: o2.downside !== void 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63142
|
-
/* @__PURE__ */ jsx$1(Text, { fontSize: "10.5px", fontFamily: "mono", color: "fg.danger", flexShrink: 0, children: fmt(decision, o2.downside, true) }),
|
|
63431
|
+
/* @__PURE__ */ jsx$1(Text, { fontSize: "10.5px", fontFamily: "mono", color: "fg.danger", flexShrink: 0, children: fmt(words, decision, o2.downside, true) }),
|
|
63143
63432
|
/* @__PURE__ */ jsx$1(Box, { height: "12px", width: `${Math.round(downFrac * 100)}%`, bg: "fg.danger", opacity: 0.55 })
|
|
63144
63433
|
] }) }),
|
|
63145
63434
|
/* @__PURE__ */ jsx$1(Box, { display: "flex", alignItems: "center", gap: "6px", height: "16px", borderLeftWidth: "1px", borderColor: "border.strong", children: o2.value > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63146
63435
|
/* @__PURE__ */ jsx$1(Box, { height: "12px", width: `${Math.round(upFrac * 100)}%`, bg: signed2 ? "fg.success" : "fg.subtle", opacity: 0.6 }),
|
|
63147
|
-
/* @__PURE__ */ jsx$1(Text, { fontSize: "10.5px", fontFamily: "mono", color: signed2 ? "fg.success" : "fg.muted", flexShrink: 0, children: fmt(decision, o2.value, signed2) })
|
|
63436
|
+
/* @__PURE__ */ jsx$1(Text, { fontSize: "10.5px", fontFamily: "mono", color: signed2 ? "fg.success" : "fg.muted", flexShrink: 0, children: fmt(words, decision, o2.value, signed2) })
|
|
63148
63437
|
] }) })
|
|
63149
63438
|
]
|
|
63150
63439
|
},
|
|
@@ -63158,8 +63447,9 @@ const ANSWERS = [
|
|
|
63158
63447
|
{ literal: "no", label: "No" },
|
|
63159
63448
|
{ literal: "unknown", label: "Don't know" }
|
|
63160
63449
|
];
|
|
63161
|
-
const JudgementFacet = memo(function JudgementFacet2({ decision, handle,
|
|
63450
|
+
const JudgementFacet = memo(function JudgementFacet2({ decision, handle, contract }) {
|
|
63162
63451
|
var _a2;
|
|
63452
|
+
const words = useFormatters();
|
|
63163
63453
|
const button = useRecipe({ key: "button" });
|
|
63164
63454
|
const input = useRecipe({ key: "input" });
|
|
63165
63455
|
const judgement = handle.judgementFor(decision.id);
|
|
@@ -63172,11 +63462,12 @@ const JudgementFacet = memo(function JudgementFacet2({ decision, handle, leverPa
|
|
|
63172
63462
|
if (knowledge !== stagedKnowledge) handle.addKnowledge(decision.id, knowledge);
|
|
63173
63463
|
}, [knowledge, stagedKnowledge, handle, decision.id]);
|
|
63174
63464
|
const levers = useMemo(
|
|
63175
|
-
() => decision.levers.filter((l2) => leverPayloadEditable(
|
|
63176
|
-
[decision.levers,
|
|
63465
|
+
() => decision.levers.filter((l2) => leverPayloadEditable(contract == null ? void 0 : contract.payloads.get(l2.case))),
|
|
63466
|
+
[decision.levers, contract]
|
|
63177
63467
|
);
|
|
63178
63468
|
const [leverCase, setLeverCase] = useState(((_a2 = levers[0]) == null ? void 0 : _a2.case) ?? "");
|
|
63179
63469
|
const activeLever = levers.find((l2) => l2.case === leverCase) ?? levers[0];
|
|
63470
|
+
const activePayload = activeLever === void 0 ? void 0 : contract == null ? void 0 : contract.payloads.get(activeLever.case);
|
|
63180
63471
|
const gate = handle.commitStateFor(decision.id);
|
|
63181
63472
|
const gateHint = (gate == null ? void 0 : gate.type) === "gated" ? gate.value === 1n ? "Answer the judgement question to enable apply" : `Answer the ${gate.value} judgement questions to enable apply` : (gate == null ? void 0 : gate.type) === "blocked" ? "Commit blocked — an answer contradicts the recommendation" : (gate == null ? void 0 : gate.type) === "handoff" ? "Awaiting handoff — an answer was don't know" : null;
|
|
63182
63473
|
const onInject = useCallback((constraint) => {
|
|
@@ -63222,8 +63513,7 @@ const JudgementFacet = memo(function JudgementFacet2({ decision, handle, leverPa
|
|
|
63222
63513
|
(levers.length > 0 || judgement.constraints.length > 0) && /* @__PURE__ */ jsxs(Box, { display: "flex", flexDirection: "column", gap: "6px", children: [
|
|
63223
63514
|
/* @__PURE__ */ jsx$1(Text, { ...caption, children: "Inject constraint · next run folds it in" }),
|
|
63224
63515
|
judgement.constraints.length > 0 && /* @__PURE__ */ jsx$1(Box, { display: "flex", gap: "12px", flexWrap: "wrap", children: judgement.constraints.map((c2, i) => {
|
|
63225
|
-
const
|
|
63226
|
-
const f2 = formatConstraint(c2, leverPayloads[tag], decision.levers);
|
|
63516
|
+
const f2 = formatConstraint(c2, contract, decision.levers, words);
|
|
63227
63517
|
return /* @__PURE__ */ jsxs(Text, { as: "span", fontFamily: "mono", fontSize: "11px", children: [
|
|
63228
63518
|
/* @__PURE__ */ jsx$1(Text, { as: "span", color: "accent.brand", fontWeight: "semibold", children: f2.lever }),
|
|
63229
63519
|
" ",
|
|
@@ -63232,7 +63522,7 @@ const JudgementFacet = memo(function JudgementFacet2({ decision, handle, leverPa
|
|
|
63232
63522
|
/* @__PURE__ */ jsx$1(Text, { as: "span", fontWeight: "semibold", children: f2.value })
|
|
63233
63523
|
] }, i);
|
|
63234
63524
|
}) }),
|
|
63235
|
-
activeLever !== void 0 && /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", gap: "8px", flexWrap: "wrap", children: [
|
|
63525
|
+
activeLever !== void 0 && activePayload !== void 0 && /* @__PURE__ */ jsxs(Box, { display: "flex", alignItems: "center", gap: "8px", flexWrap: "wrap", children: [
|
|
63236
63526
|
levers.length > 1 ? /* @__PURE__ */ jsx$1(Box, { flexShrink: 0, css: { "& [data-scope=select][data-part=root]": { width: "auto", minWidth: "160px" } }, children: /* @__PURE__ */ jsx$1(
|
|
63237
63527
|
EastChakraSelect,
|
|
63238
63528
|
{
|
|
@@ -63254,7 +63544,7 @@ const JudgementFacet = memo(function JudgementFacet2({ decision, handle, leverPa
|
|
|
63254
63544
|
LeverEditor,
|
|
63255
63545
|
{
|
|
63256
63546
|
leverCase: activeLever.case,
|
|
63257
|
-
payload:
|
|
63547
|
+
payload: activePayload,
|
|
63258
63548
|
onInject
|
|
63259
63549
|
},
|
|
63260
63550
|
activeLever.case
|
|
@@ -63277,11 +63567,54 @@ const JudgementFacet = memo(function JudgementFacet2({ decision, handle, leverPa
|
|
|
63277
63567
|
] })
|
|
63278
63568
|
] });
|
|
63279
63569
|
});
|
|
63570
|
+
function body(type) {
|
|
63571
|
+
return type.type === "Recursive" && type.value.type === "wrapper" ? type.value.value.inner : type;
|
|
63572
|
+
}
|
|
63573
|
+
function constraintContractOf(judgementsType) {
|
|
63574
|
+
const dict = body(judgementsType);
|
|
63575
|
+
if (dict.type !== "Dict") return void 0;
|
|
63576
|
+
const record = body(dict.value.value);
|
|
63577
|
+
if (record.type !== "Struct") return void 0;
|
|
63578
|
+
const field = record.value.find((f2) => f2.name === "constraints");
|
|
63579
|
+
if (field === void 0) return void 0;
|
|
63580
|
+
const constraints = body(field.type);
|
|
63581
|
+
if (constraints.type !== "Array") return void 0;
|
|
63582
|
+
const contract = constraints.value;
|
|
63583
|
+
const cases = body(contract);
|
|
63584
|
+
if (cases.type !== "Variant") return void 0;
|
|
63585
|
+
return {
|
|
63586
|
+
type: contract,
|
|
63587
|
+
payloads: new Map(cases.value.map((c2) => [c2.name, c2.type]))
|
|
63588
|
+
};
|
|
63589
|
+
}
|
|
63590
|
+
function useConstraintContract(ref) {
|
|
63591
|
+
const workspace = getReactiveDatasetCache().getConfig().workspace ?? "";
|
|
63592
|
+
return useMemo(() => {
|
|
63593
|
+
if (ref === null) return void 0;
|
|
63594
|
+
const judgements = getBindingTypes(workspace, ref.judgements.source);
|
|
63595
|
+
return judgements === void 0 ? void 0 : constraintContractOf(judgements.sourceType);
|
|
63596
|
+
}, [ref, workspace]);
|
|
63597
|
+
}
|
|
63280
63598
|
const URGENCY_RANK = {
|
|
63281
63599
|
overdue: 0,
|
|
63282
63600
|
due: 1,
|
|
63283
63601
|
routine: 2
|
|
63284
63602
|
};
|
|
63603
|
+
const compareInstants = compareFor(DateTimeType);
|
|
63604
|
+
const compareValues = compareFor(FloatType);
|
|
63605
|
+
function compareByUrgency(a2, b2) {
|
|
63606
|
+
const rank = URGENCY_RANK[a2.urgency.type] - URGENCY_RANK[b2.urgency.type];
|
|
63607
|
+
if (rank !== 0) return rank;
|
|
63608
|
+
const da = a2.deadline.type === "some" ? a2.deadline.value : void 0;
|
|
63609
|
+
const db = b2.deadline.type === "some" ? b2.deadline.value : void 0;
|
|
63610
|
+
if (da !== void 0 && db !== void 0) {
|
|
63611
|
+
const byDeadline = compareInstants(da, db);
|
|
63612
|
+
if (byDeadline !== 0) return byDeadline;
|
|
63613
|
+
} else if (da !== db) {
|
|
63614
|
+
return da === void 0 ? 1 : -1;
|
|
63615
|
+
}
|
|
63616
|
+
return compareValues(b2.value, a2.value);
|
|
63617
|
+
}
|
|
63285
63618
|
const URGENCY_GROUP_LABEL = {
|
|
63286
63619
|
overdue: "Overdue",
|
|
63287
63620
|
due: "Due today",
|
|
@@ -63328,10 +63661,10 @@ const URGENCY_TONE = {
|
|
|
63328
63661
|
};
|
|
63329
63662
|
const EXIT_MS = 560;
|
|
63330
63663
|
const NARROW_PX = 560;
|
|
63331
|
-
function decisionValue(d2, n2, showSign = false) {
|
|
63332
|
-
return
|
|
63664
|
+
function decisionValue(words, d2, n2, showSign = false) {
|
|
63665
|
+
return words.value(n2, getSomeorUndefined(d2.format), showSign);
|
|
63333
63666
|
}
|
|
63334
|
-
function deadlineSuffix(d2) {
|
|
63667
|
+
function deadlineSuffix(d2, words) {
|
|
63335
63668
|
const deadline = getSomeorUndefined(d2.deadline);
|
|
63336
63669
|
if (deadline === void 0) return "";
|
|
63337
63670
|
if (d2.urgency.type === "overdue") {
|
|
@@ -63340,34 +63673,16 @@ function deadlineSuffix(d2) {
|
|
|
63340
63673
|
if (hours < 48) return ` ${hours}h`;
|
|
63341
63674
|
return ` ${Math.round(hours / 24)}d`;
|
|
63342
63675
|
}
|
|
63343
|
-
if (d2.urgency.type === "due") {
|
|
63344
|
-
const h2 = deadline.getHours();
|
|
63345
|
-
const m2 = deadline.getMinutes();
|
|
63346
|
-
const meridiem = h2 >= 12 ? "pm" : "am";
|
|
63347
|
-
const clock2 = h2 % 12 === 0 ? 12 : h2 % 12;
|
|
63348
|
-
return m2 === 0 ? ` ${clock2}${meridiem}` : ` ${clock2}:${String(m2).padStart(2, "0")}${meridiem}`;
|
|
63349
|
-
}
|
|
63676
|
+
if (d2.urgency.type === "due") return ` ${words.time(deadline)}`;
|
|
63350
63677
|
return "";
|
|
63351
63678
|
}
|
|
63352
|
-
function
|
|
63353
|
-
const cache3 = getReactiveDatasetCache();
|
|
63354
|
-
const workspace = cache3.getConfig().workspace ?? "";
|
|
63355
|
-
return useMemo(() => {
|
|
63356
|
-
var _a2, _b2, _c2;
|
|
63357
|
-
if (!ref) return {};
|
|
63358
|
-
const judgements = getBindingTypes(workspace, ref.judgements.source);
|
|
63359
|
-
if (!(judgements == null ? void 0 : judgements.sourceType)) return {};
|
|
63360
|
-
const root2 = normalizeTypeValue(judgements.sourceType);
|
|
63361
|
-
const constraint = (_c2 = (_b2 = (_a2 = root2.value) == null ? void 0 : _a2.fields) == null ? void 0 : _b2["constraints"]) == null ? void 0 : _c2.value;
|
|
63362
|
-
return (constraint == null ? void 0 : constraint.type) === "Variant" ? constraint.cases ?? {} : {};
|
|
63363
|
-
}, [ref, workspace]);
|
|
63364
|
-
}
|
|
63365
|
-
const Row = memo(function Row2({ decision, handle, selected: selected2, narrow, leverPayloads, modify, evidence, defaultFacet, facetInclude, apply: apply2, reject: reject2, leaving, storageKey }) {
|
|
63679
|
+
const Row = memo(function Row2({ decision, handle, selected: selected2, narrow, contract, modify, evidence, defaultFacet, facetInclude, apply: apply2, reject: reject2, leaving, storageKey }) {
|
|
63366
63680
|
var _a2, _b2;
|
|
63367
63681
|
const dq = useSlotRecipe({ key: "decisionQueue" });
|
|
63368
63682
|
const status = useSlotRecipe({ key: "status" });
|
|
63369
63683
|
const tabs = useSlotRecipe({ key: "facetTabs" });
|
|
63370
63684
|
const button = useRecipe({ key: "button" });
|
|
63685
|
+
const words = useFormatters();
|
|
63371
63686
|
const rs = dq({});
|
|
63372
63687
|
const ts = tabs({});
|
|
63373
63688
|
const st = status({ status: URGENCY_TONE[decision.urgency.type], size: "md" });
|
|
@@ -63393,10 +63708,15 @@ const Row = memo(function Row2({ decision, handle, selected: selected2, narrow,
|
|
|
63393
63708
|
const handleReject = useCallback(() => {
|
|
63394
63709
|
reject2(decision);
|
|
63395
63710
|
}, [reject2, decision]);
|
|
63711
|
+
const stageUpdate = handle.update;
|
|
63712
|
+
const updateDecision = useCallback((next2) => {
|
|
63713
|
+
stageUpdate(next2);
|
|
63714
|
+
return null;
|
|
63715
|
+
}, [stageUpdate]);
|
|
63396
63716
|
const probe = useMemo(() => {
|
|
63397
63717
|
if (!selected2 || facet !== "modify" || !modify) return null;
|
|
63398
|
-
return modify(decision,
|
|
63399
|
-
}, [selected2, facet, modify, decision,
|
|
63718
|
+
return modify(decision, updateDecision);
|
|
63719
|
+
}, [selected2, facet, modify, decision, updateDecision]);
|
|
63400
63720
|
const canvas = useMemo(() => {
|
|
63401
63721
|
if (!selected2 || facet !== "evidence" || !evidence) return null;
|
|
63402
63722
|
return evidence(decision);
|
|
@@ -63445,11 +63765,11 @@ const Row = memo(function Row2({ decision, handle, selected: selected2, narrow,
|
|
|
63445
63765
|
/* @__PURE__ */ jsx$1(Box, { as: "span", css: st.indicator }),
|
|
63446
63766
|
/* @__PURE__ */ jsxs(Box, { as: "span", css: st.label, children: [
|
|
63447
63767
|
decision.urgency.type,
|
|
63448
|
-
deadlineSuffix(decision)
|
|
63768
|
+
deadlineSuffix(decision, words)
|
|
63449
63769
|
] })
|
|
63450
63770
|
] });
|
|
63451
63771
|
const valueSigned = ((_b2 = getSomeorUndefined(decision.valueAxis)) == null ? void 0 : _b2.signed) ?? true;
|
|
63452
|
-
const valueText = /* @__PURE__ */ jsx$1(Text, { fontFamily: "mono", fontWeight: "semibold", textAlign: "right", ...valueSigned && decision.value >= 0 && selected2 ? { color: "fg.success" } : {}, children: decisionValue(decision, decision.value, valueSigned && selected2) });
|
|
63772
|
+
const valueText = /* @__PURE__ */ jsx$1(Text, { fontFamily: "mono", fontWeight: "semibold", textAlign: "right", ...valueSigned && decision.value >= 0 && selected2 ? { color: "fg.success" } : {}, children: decisionValue(words, decision, decision.value, valueSigned && selected2) });
|
|
63453
63773
|
return /* @__PURE__ */ jsxs(Box, { css: rs.rowShell, ...leaving ? { "data-leaving": leaving } : {}, children: [
|
|
63454
63774
|
narrow ? /* @__PURE__ */ jsxs(Box, { px: "14px", py: "10px", children: [
|
|
63455
63775
|
/* @__PURE__ */ jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "baseline", children: [
|
|
@@ -63473,7 +63793,7 @@ const Row = memo(function Row2({ decision, handle, selected: selected2, narrow,
|
|
|
63473
63793
|
selected2 && /* @__PURE__ */ jsxs(Box, { px: narrow ? "14px" : "18px", py: "12px", borderTopWidth: "1px", borderColor: "border.subtle", bg: "bg.canvas", children: [
|
|
63474
63794
|
facet === "evidence" && /* @__PURE__ */ jsx$1(EvidenceFacet, { decision, children: canvas != null && /* @__PURE__ */ jsx$1(EastChakraComponent, { value: canvas, storageKey: `${storageKey}-evidence-${decision.id}` }) }),
|
|
63475
63795
|
facet === "options" && /* @__PURE__ */ jsx$1(OptionsFacet, { decision, narrow }),
|
|
63476
|
-
facet === "judgement" && /* @__PURE__ */ jsx$1(JudgementFacet, { decision, handle,
|
|
63796
|
+
facet === "judgement" && /* @__PURE__ */ jsx$1(JudgementFacet, { decision, handle, contract }),
|
|
63477
63797
|
facet === "modify" && probe != null && /* @__PURE__ */ jsx$1(EastChakraComponent, { value: probe, storageKey: `${storageKey}-modify-${decision.id}` })
|
|
63478
63798
|
] })
|
|
63479
63799
|
] });
|
|
@@ -63482,6 +63802,7 @@ const RoutineGroup = memo(function RoutineGroup2({ routine, acceptAll, leaving,
|
|
|
63482
63802
|
const dq = useSlotRecipe({ key: "decisionQueue" });
|
|
63483
63803
|
const status = useSlotRecipe({ key: "status" });
|
|
63484
63804
|
const button = useRecipe({ key: "button" });
|
|
63805
|
+
const words = useFormatters();
|
|
63485
63806
|
const rs = dq({});
|
|
63486
63807
|
const st = status({ status: "neutral", size: "md" });
|
|
63487
63808
|
const total = useMemo(() => routine.reduce((acc, d2) => acc + d2.value, 0), [routine]);
|
|
@@ -63503,15 +63824,15 @@ const RoutineGroup = memo(function RoutineGroup2({ routine, acceptAll, leaving,
|
|
|
63503
63824
|
d2.kind
|
|
63504
63825
|
] })
|
|
63505
63826
|
] }),
|
|
63506
|
-
/* @__PURE__ */ jsx$1(Box, { css: rs.routineValue, children: decisionValue(d2, d2.value) })
|
|
63827
|
+
/* @__PURE__ */ jsx$1(Box, { css: rs.routineValue, children: decisionValue(words, d2, d2.value) })
|
|
63507
63828
|
] }) }, d2.id)),
|
|
63508
63829
|
/* @__PURE__ */ jsxs(Box, { css: rs.summary, ...narrow ? { marginLeft: "0", flexWrap: "wrap" } : {}, children: [
|
|
63509
63830
|
/* @__PURE__ */ jsxs(Box, { as: "span", css: rs.summaryCap, children: [
|
|
63510
|
-
routine.length,
|
|
63831
|
+
words.number(routine.length),
|
|
63511
63832
|
" routine"
|
|
63512
63833
|
] }),
|
|
63513
63834
|
/* @__PURE__ */ jsx$1(Text, { as: "span", color: "fg.subtle", children: "·" }),
|
|
63514
|
-
/* @__PURE__ */ jsx$1(Text, { as: "span", fontFamily: "mono", fontWeight: "semibold", children:
|
|
63835
|
+
/* @__PURE__ */ jsx$1(Text, { as: "span", fontFamily: "mono", fontWeight: "semibold", children: words.value(total, format2) }),
|
|
63515
63836
|
/* @__PURE__ */ jsx$1(Text, { as: "span", color: "fg.muted", children: "total" }),
|
|
63516
63837
|
acceptAll && /* @__PURE__ */ jsx$1(Box, { as: "button", css: button({ variant: "solid", size: "xs" }), ml: "auto", onClick: handleAcceptAll, children: "Accept all" })
|
|
63517
63838
|
] })
|
|
@@ -63520,6 +63841,7 @@ const RoutineGroup = memo(function RoutineGroup2({ routine, acceptAll, leaving,
|
|
|
63520
63841
|
const GroupHead = memo(function GroupHead2({ group: group2, collapsible, collapsed, onToggle, acceptAll }) {
|
|
63521
63842
|
const dq = useSlotRecipe({ key: "decisionQueue" });
|
|
63522
63843
|
const button = useRecipe({ key: "button" });
|
|
63844
|
+
const words = useFormatters();
|
|
63523
63845
|
const rs = dq({});
|
|
63524
63846
|
const format2 = group2.decisions[0] ? getSomeorUndefined(group2.decisions[0].format) : void 0;
|
|
63525
63847
|
const handleToggle = useCallback(() => {
|
|
@@ -63534,11 +63856,11 @@ const GroupHead = memo(function GroupHead2({ group: group2, collapsible, collaps
|
|
|
63534
63856
|
/* @__PURE__ */ jsxs(Box, { as: "span", css: rs.groupLabel, children: [
|
|
63535
63857
|
group2.label,
|
|
63536
63858
|
" · ",
|
|
63537
|
-
group2.decisions.length
|
|
63859
|
+
words.number(group2.decisions.length)
|
|
63538
63860
|
] }),
|
|
63539
63861
|
/* @__PURE__ */ jsxs(Box, { as: "span", css: rs.groupSummary, children: [
|
|
63540
|
-
|
|
63541
|
-
group2.pastSla > 0 ? ` · ${group2.pastSla} past SLA` : ""
|
|
63862
|
+
words.value(group2.total, format2),
|
|
63863
|
+
group2.pastSla > 0 ? ` · ${words.number(group2.pastSla)} past SLA` : ""
|
|
63542
63864
|
] }),
|
|
63543
63865
|
acceptAll && /* @__PURE__ */ jsx$1(Box, { as: "button", css: button({ variant: "solid", size: "xs" }), onClick: handleAcceptAll, children: "Accept all" })
|
|
63544
63866
|
] });
|
|
@@ -63550,10 +63872,11 @@ const EastChakraDecisionQueue = memo(function EastChakraDecisionQueue2({ value,
|
|
|
63550
63872
|
const dq = useSlotRecipe({ key: "decisionQueue" });
|
|
63551
63873
|
const qs = dq({});
|
|
63552
63874
|
const chip = useRecipe({ key: "chip" });
|
|
63875
|
+
const words = useFormatters();
|
|
63553
63876
|
const handleRef = value.handle;
|
|
63554
63877
|
const handle = useDecisionHandle(handleRef);
|
|
63555
63878
|
const decisions = handle.decisions;
|
|
63556
|
-
const
|
|
63879
|
+
const contract = useConstraintContract(handleRef);
|
|
63557
63880
|
const railAffordances = getSomeorUndefined(value.affordances);
|
|
63558
63881
|
const sliceHandle = getSomeorUndefined(value.slice) ?? null;
|
|
63559
63882
|
useSliceReactivity(sliceHandle == null ? void 0 : sliceHandle.key);
|
|
@@ -63593,14 +63916,8 @@ const EastChakraDecisionQueue = memo(function EastChakraDecisionQueue2({ value,
|
|
|
63593
63916
|
const heading = getSomeorUndefined(value.heading) ?? "Decisions waiting";
|
|
63594
63917
|
const onApply = useMemo(() => getSomeorUndefined(value.onApply), [value.onApply]);
|
|
63595
63918
|
const onReject = useMemo(() => getSomeorUndefined(value.onReject), [value.onReject]);
|
|
63596
|
-
const modify = useMemo(
|
|
63597
|
-
|
|
63598
|
-
[value.modify]
|
|
63599
|
-
);
|
|
63600
|
-
const evidence = useMemo(
|
|
63601
|
-
() => getSomeorUndefined(value.evidence),
|
|
63602
|
-
[value.evidence]
|
|
63603
|
-
);
|
|
63919
|
+
const modify = useMemo(() => getSomeorUndefined(value.modify), [value.modify]);
|
|
63920
|
+
const evidence = useMemo(() => getSomeorUndefined(value.evidence), [value.evidence]);
|
|
63604
63921
|
const defaultFacet = ((_a2 = getSomeorUndefined(value.defaultFacet)) == null ? void 0 : _a2.type) ?? "evidence";
|
|
63605
63922
|
const facetInclude = useMemo(() => {
|
|
63606
63923
|
const facets = getSomeorUndefined(value.facets);
|
|
@@ -63649,15 +63966,7 @@ const EastChakraDecisionQueue = memo(function EastChakraDecisionQueue2({ value,
|
|
|
63649
63966
|
for (const { decision } of exiting.values()) {
|
|
63650
63967
|
if (!merged2.some((d2) => d2.id === decision.id)) merged2.push(decision);
|
|
63651
63968
|
}
|
|
63652
|
-
merged2.sort(
|
|
63653
|
-
var _a3, _b2;
|
|
63654
|
-
const r2 = URGENCY_RANK[a2.urgency.type] - URGENCY_RANK[b2.urgency.type];
|
|
63655
|
-
if (r2 !== 0) return r2;
|
|
63656
|
-
const da = ((_a3 = getSomeorUndefined(a2.deadline)) == null ? void 0 : _a3.getTime()) ?? Infinity;
|
|
63657
|
-
const db = ((_b2 = getSomeorUndefined(b2.deadline)) == null ? void 0 : _b2.getTime()) ?? Infinity;
|
|
63658
|
-
if (da !== db) return da - db;
|
|
63659
|
-
return b2.value - a2.value;
|
|
63660
|
-
});
|
|
63969
|
+
merged2.sort(compareByUrgency);
|
|
63661
63970
|
return {
|
|
63662
63971
|
merged: merged2,
|
|
63663
63972
|
active: merged2.filter((d2) => d2.urgency.type !== "routine"),
|
|
@@ -63696,7 +64005,7 @@ const EastChakraDecisionQueue = memo(function EastChakraDecisionQueue2({ value,
|
|
|
63696
64005
|
handle,
|
|
63697
64006
|
selected: selectedId === d2.id,
|
|
63698
64007
|
narrow,
|
|
63699
|
-
|
|
64008
|
+
contract,
|
|
63700
64009
|
modify,
|
|
63701
64010
|
evidence,
|
|
63702
64011
|
defaultFacet,
|
|
@@ -63723,13 +64032,13 @@ const EastChakraDecisionQueue = memo(function EastChakraDecisionQueue2({ value,
|
|
|
63723
64032
|
) }),
|
|
63724
64033
|
/* @__PURE__ */ jsxs(Box, { css: es.meta, gap: "10px", children: [
|
|
63725
64034
|
/* @__PURE__ */ jsxs(Box, { as: "span", children: [
|
|
63726
|
-
/* @__PURE__ */ jsx$1(Text, { as: "span", color: "fg", fontWeight: "semibold", children: visible }),
|
|
64035
|
+
/* @__PURE__ */ jsx$1(Text, { as: "span", color: "fg", fontWeight: "semibold", children: words.number(visible) }),
|
|
63727
64036
|
narrow ? "" : " decisions"
|
|
63728
64037
|
] }),
|
|
63729
64038
|
pastSla > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63730
64039
|
/* @__PURE__ */ jsx$1(Box, { as: "span", css: es.sep, children: "·" }),
|
|
63731
64040
|
/* @__PURE__ */ jsxs(Box, { as: "span", children: [
|
|
63732
|
-
/* @__PURE__ */ jsx$1(Text, { as: "span", color: "fg.danger", fontWeight: "semibold", children: pastSla }),
|
|
64041
|
+
/* @__PURE__ */ jsx$1(Text, { as: "span", color: "fg.danger", fontWeight: "semibold", children: words.number(pastSla) }),
|
|
63733
64042
|
narrow ? " SLA" : " past SLA"
|
|
63734
64043
|
] })
|
|
63735
64044
|
] })
|
|
@@ -63791,34 +64100,24 @@ function verdictPresentation(verdict) {
|
|
|
63791
64100
|
return { tone: "warning", verb: "handed off", detail: verdict.value !== "" ? verdict.value : null };
|
|
63792
64101
|
}
|
|
63793
64102
|
}
|
|
63794
|
-
function formatResolvedAt(j2) {
|
|
64103
|
+
function formatResolvedAt(j2, words) {
|
|
63795
64104
|
if (j2.resolvedAt.type !== "some") return null;
|
|
63796
64105
|
const d2 = j2.resolvedAt.value;
|
|
63797
|
-
|
|
63798
|
-
const time2 = `${String(d2.getHours()).padStart(2, "0")}:${String(d2.getMinutes()).padStart(2, "0")}`;
|
|
63799
|
-
return `${month} ${d2.getDate()} · ${time2}`;
|
|
64106
|
+
return `${words.monthDay(d2)} · ${words.time(d2)}`;
|
|
63800
64107
|
}
|
|
63801
64108
|
const EastChakraDecisionJournal = memo(function EastChakraDecisionJournal2({ value }) {
|
|
63802
64109
|
const eyebrow = useSlotRecipe({ key: "eyebrowRow" });
|
|
63803
64110
|
const status = useSlotRecipe({ key: "status" });
|
|
63804
64111
|
const es = eyebrow({});
|
|
64112
|
+
const words = useFormatters();
|
|
63805
64113
|
const handle = useDecisionHandle(value.handle);
|
|
63806
64114
|
const heading = getSomeorUndefined(value.heading) ?? "Decision journal";
|
|
63807
|
-
const
|
|
63808
|
-
const workspace = cache3.getConfig().workspace ?? "";
|
|
63809
|
-
const leverPayloads = useMemo(() => {
|
|
63810
|
-
var _a2, _b2, _c2;
|
|
63811
|
-
const judgements = getBindingTypes(workspace, value.handle.judgements.source);
|
|
63812
|
-
if (!(judgements == null ? void 0 : judgements.sourceType)) return {};
|
|
63813
|
-
const root2 = normalizeTypeValue(judgements.sourceType);
|
|
63814
|
-
const constraint = (_c2 = (_b2 = (_a2 = root2.value) == null ? void 0 : _a2.fields) == null ? void 0 : _b2["constraints"]) == null ? void 0 : _c2.value;
|
|
63815
|
-
return (constraint == null ? void 0 : constraint.type) === "Variant" ? constraint.cases ?? {} : {};
|
|
63816
|
-
}, [workspace, value.handle]);
|
|
64115
|
+
const contract = useConstraintContract(value.handle);
|
|
63817
64116
|
const entries = useMemo(() => handle.journal ?? [], [handle.journal]);
|
|
63818
64117
|
return /* @__PURE__ */ jsxs(Box, { borderWidth: "1px", borderColor: "border.strong", borderRadius: "6px", background: "bg.canvas", overflow: "hidden", children: [
|
|
63819
64118
|
/* @__PURE__ */ jsxs(Box, { css: es.root, children: [
|
|
63820
64119
|
/* @__PURE__ */ jsx$1(Box, { css: es.lbl, children: heading }),
|
|
63821
|
-
/* @__PURE__ */ jsx$1(Box, { css: es.meta, children: entries.length === 1 ? "1 entry" : `${entries.length} entries` })
|
|
64120
|
+
/* @__PURE__ */ jsx$1(Box, { css: es.meta, children: entries.length === 1 ? "1 entry" : `${words.number(entries.length)} entries` })
|
|
63822
64121
|
] }),
|
|
63823
64122
|
/* @__PURE__ */ jsx$1(
|
|
63824
64123
|
Box,
|
|
@@ -63830,7 +64129,7 @@ const EastChakraDecisionJournal = memo(function EastChakraDecisionJournal2({ val
|
|
|
63830
64129
|
if (!verdict) return null;
|
|
63831
64130
|
const { tone, verb, detail } = verdictPresentation(verdict);
|
|
63832
64131
|
const st = status({ status: tone, size: "md" });
|
|
63833
|
-
const when = formatResolvedAt(j2);
|
|
64132
|
+
const when = formatResolvedAt(j2, words);
|
|
63834
64133
|
const knowledge = j2.knowledge.type === "some" && j2.knowledge.value !== "" ? j2.knowledge.value : null;
|
|
63835
64134
|
return /* @__PURE__ */ jsxs(
|
|
63836
64135
|
Box,
|
|
@@ -63869,8 +64168,7 @@ const EastChakraDecisionJournal = memo(function EastChakraDecisionJournal2({ val
|
|
|
63869
64168
|
}
|
|
63870
64169
|
),
|
|
63871
64170
|
j2.constraints.length > 0 && /* @__PURE__ */ jsx$1(Box, { display: "flex", gap: "12px", flexWrap: "wrap", children: j2.constraints.map((c2, k2) => {
|
|
63872
|
-
const
|
|
63873
|
-
const f2 = formatConstraint(c2, leverPayloads[tag]);
|
|
64171
|
+
const f2 = formatConstraint(c2, contract, void 0, words);
|
|
63874
64172
|
return /* @__PURE__ */ jsx$1(ClauseChip, { field: f2.lever, op: f2.op, value: f2.value }, k2);
|
|
63875
64173
|
}) })
|
|
63876
64174
|
]
|
|
@@ -64189,6 +64487,7 @@ function useDatasetValue(apiUrl, repo, workspace, datasetPath, options2) {
|
|
|
64189
64487
|
const { requestOptions, queryOverrides, enabled = true, hash: hash2, platforms, type } = options2;
|
|
64190
64488
|
const platformImpls = platforms ?? defaultPlatformImplementations;
|
|
64191
64489
|
const reqOpts = requestOptions ?? { token: null };
|
|
64490
|
+
const queryClient = useQueryClient();
|
|
64192
64491
|
const pathParts = useMemo(
|
|
64193
64492
|
() => (datasetPath == null ? void 0 : datasetPath.split(".").filter(Boolean).map((v3) => variant("field", v3))) ?? [],
|
|
64194
64493
|
[datasetPath]
|
|
@@ -64198,8 +64497,14 @@ function useDatasetValue(apiUrl, repo, workspace, datasetPath, options2) {
|
|
|
64198
64497
|
queryFn: async () => {
|
|
64199
64498
|
const result = await datasetGet(apiUrl, repo, workspace, pathParts, reqOpts);
|
|
64200
64499
|
const decoded = decodeBeast2For(type, { platform: platformImpls })(result.data);
|
|
64201
|
-
|
|
64500
|
+
const value = { decoded, sizeBytes: result.data.length, hash: result.hash ?? hash2 ?? null };
|
|
64501
|
+
if (value.hash !== hash2) {
|
|
64502
|
+
queryClient.setQueryData(["datasetValue", apiUrl, repo, workspace, datasetPath, value.hash], value);
|
|
64503
|
+
void queryClient.invalidateQueries({ queryKey: ["datasetStatus", apiUrl, repo, workspace, datasetPath] });
|
|
64504
|
+
}
|
|
64505
|
+
return value;
|
|
64202
64506
|
},
|
|
64507
|
+
select: (value) => value.hash === (hash2 ?? null) ? value : void 0,
|
|
64203
64508
|
enabled: enabled && !!workspace && !!datasetPath && hash2 != null,
|
|
64204
64509
|
...queryOverrides
|
|
64205
64510
|
});
|
|
@@ -64265,14 +64570,6 @@ function useTaskDetails(apiUrl, repo, workspace, taskName, options2) {
|
|
|
64265
64570
|
...options2 == null ? void 0 : options2.queryOverrides
|
|
64266
64571
|
});
|
|
64267
64572
|
}
|
|
64268
|
-
function getTaskKind(details) {
|
|
64269
|
-
var _a2;
|
|
64270
|
-
return ((_a2 = details.kind) == null ? void 0 : _a2.type) === "some" ? details.kind.value : null;
|
|
64271
|
-
}
|
|
64272
|
-
function getTaskMetadata(details) {
|
|
64273
|
-
var _a2;
|
|
64274
|
-
return ((_a2 = details.metadata) == null ? void 0 : _a2.type) === "some" ? details.metadata.value : null;
|
|
64275
|
-
}
|
|
64276
64573
|
const variantStyles = {
|
|
64277
64574
|
// Mode-aware semantic tokens (the raw `red.50` / `gray.50` washes rendered
|
|
64278
64575
|
// as bright light boxes in dark mode — #362).
|
|
@@ -64410,6 +64707,10 @@ function pagingDebug(...args) {
|
|
|
64410
64707
|
console.info("[e3-paging]", ...args);
|
|
64411
64708
|
}
|
|
64412
64709
|
const PAGE_SIZE = 500;
|
|
64710
|
+
function servedPageSize(requested, page) {
|
|
64711
|
+
const trimmed = page.count < requested && page.offset + page.count < page.totalElements;
|
|
64712
|
+
return trimmed ? Math.max(1, page.count) : requested;
|
|
64713
|
+
}
|
|
64413
64714
|
const MAX_RETAINED_PAGES = 8;
|
|
64414
64715
|
function pageRows(type, decoded, offset) {
|
|
64415
64716
|
if (type.type === "Array") {
|
|
@@ -64449,6 +64750,7 @@ const PagedDatasetPreview = memo(function PagedDatasetPreview2({
|
|
|
64449
64750
|
onDownload,
|
|
64450
64751
|
onNotIndexed
|
|
64451
64752
|
}) {
|
|
64753
|
+
const words = useFormatters();
|
|
64452
64754
|
const queryClient = useQueryClient();
|
|
64453
64755
|
const [pages, setPages] = useState(/* @__PURE__ */ new Map());
|
|
64454
64756
|
const [totals, setTotals] = useState(null);
|
|
@@ -64456,48 +64758,69 @@ const PagedDatasetPreview = memo(function PagedDatasetPreview2({
|
|
|
64456
64758
|
const [error3, setError] = useState(null);
|
|
64457
64759
|
const [jumpRow, setJumpRow] = useState(void 0);
|
|
64458
64760
|
const inflightRef = useRef(/* @__PURE__ */ new Set());
|
|
64761
|
+
const shownRef = useRef({ path: path2, hash: hash2 });
|
|
64762
|
+
const [pageSize, setPageSize] = useState(PAGE_SIZE);
|
|
64763
|
+
const pageSizeRef = useRef(PAGE_SIZE);
|
|
64459
64764
|
useEffect(() => {
|
|
64460
64765
|
pagingDebug(`reset (path=${path2}, hash=${hash2.slice(0, 8)})`);
|
|
64766
|
+
shownRef.current = { path: path2, hash: hash2 };
|
|
64461
64767
|
setPages(/* @__PURE__ */ new Map());
|
|
64462
64768
|
setTotals(null);
|
|
64463
64769
|
setError(null);
|
|
64464
64770
|
setJumpRow(void 0);
|
|
64465
|
-
inflightRef.current
|
|
64771
|
+
inflightRef.current = /* @__PURE__ */ new Set();
|
|
64772
|
+
pageSizeRef.current = PAGE_SIZE;
|
|
64773
|
+
setPageSize(PAGE_SIZE);
|
|
64466
64774
|
}, [path2, hash2]);
|
|
64467
64775
|
const loadPage = useCallback((pageIdx) => {
|
|
64468
|
-
|
|
64469
|
-
|
|
64776
|
+
const inflight = inflightRef.current;
|
|
64777
|
+
if (inflight.has(pageIdx)) return;
|
|
64778
|
+
inflight.add(pageIdx);
|
|
64779
|
+
const current = () => shownRef.current.path === path2 && shownRef.current.hash === hash2;
|
|
64780
|
+
const size3 = pageSizeRef.current;
|
|
64470
64781
|
setLoadingCount((n2) => n2 + 1);
|
|
64471
|
-
pagingDebug(`fetch p${pageIdx} (offset=${pageIdx *
|
|
64782
|
+
pagingDebug(`fetch p${pageIdx} (offset=${pageIdx * size3}, limit=${size3}, hash=${hash2.slice(0, 8)})`);
|
|
64472
64783
|
const pathParts2 = path2.split(".").filter(Boolean).map((v3) => variant("field", v3));
|
|
64473
64784
|
const reqOpts = requestOptions ?? { token: null };
|
|
64474
64785
|
queryClient.fetchQuery({
|
|
64475
|
-
queryKey: ["datasetPage", apiUrl, repo, workspace, path2, hash2, `p${pageIdx}`],
|
|
64786
|
+
queryKey: ["datasetPage", apiUrl, repo, workspace, path2, hash2, `p${pageIdx}@${size3}`],
|
|
64476
64787
|
// Hash-pinned: the URL is a pure function of the bytes, so any
|
|
64477
64788
|
// HTTP cache between here and the server can hold it immutably.
|
|
64478
|
-
queryFn: () => datasetGetPage(apiUrl, repo, workspace, pathParts2, { offset: pageIdx *
|
|
64789
|
+
queryFn: () => datasetGetPage(apiUrl, repo, workspace, pathParts2, { offset: pageIdx * size3, limit: size3, hash: hash2 }, reqOpts),
|
|
64479
64790
|
staleTime: Infinity
|
|
64480
64791
|
// pages of one content hash are immutable
|
|
64481
64792
|
}).then((page) => {
|
|
64793
|
+
if (!current()) return;
|
|
64794
|
+
if (size3 !== pageSizeRef.current) return;
|
|
64482
64795
|
const decoded = decodeBeast2For(type)(page.data);
|
|
64483
64796
|
const rows = pageRows(type, decoded, page.offset);
|
|
64484
64797
|
pagingDebug(
|
|
64485
64798
|
`p${pageIdx} ok: count=${page.count} rows=${rows.length} offset=${page.offset} total=${page.totalElements} segs=${page.segmentCount}`,
|
|
64486
64799
|
rows.length > 0 ? `first=${JSON.stringify(rows[0].label ?? "(derived)")}` : "(empty)"
|
|
64487
64800
|
);
|
|
64488
|
-
if (page.count < PAGE_SIZE && page.offset + page.count < page.totalElements) {
|
|
64489
|
-
pagingDebug(`p${pageIdx} SHORT page: server clamped ${PAGE_SIZE} → ${page.count}`);
|
|
64490
|
-
}
|
|
64491
64801
|
setTotals({ elements: page.totalElements, bytes: page.totalBytes });
|
|
64492
|
-
|
|
64802
|
+
const served = servedPageSize(size3, page);
|
|
64803
|
+
if (served === size3) {
|
|
64804
|
+
setPages((prev2) => new Map(prev2).set(pageIdx, rows));
|
|
64805
|
+
return;
|
|
64806
|
+
}
|
|
64807
|
+
pagingDebug(`p${pageIdx} SHORT page: served ${page.count} of ${size3} — addressing pages by ${served}`);
|
|
64808
|
+
pageSizeRef.current = served;
|
|
64809
|
+
setPageSize(served);
|
|
64810
|
+
setPages(pageIdx === 0 ? /* @__PURE__ */ new Map([[0, rows]]) : /* @__PURE__ */ new Map());
|
|
64493
64811
|
}).catch((err) => {
|
|
64494
64812
|
pagingDebug(`p${pageIdx} FAILED:`, err);
|
|
64813
|
+
if (!current()) return;
|
|
64814
|
+
if (err instanceof DatasetHashMismatchError) {
|
|
64815
|
+
void queryClient.invalidateQueries({ queryKey: ["datasetStatus", apiUrl, repo, workspace, path2] });
|
|
64816
|
+
return;
|
|
64817
|
+
}
|
|
64495
64818
|
if (err instanceof ApiError && err.code === "dataset_not_indexed") {
|
|
64496
64819
|
onNotIndexed == null ? void 0 : onNotIndexed();
|
|
64497
64820
|
}
|
|
64498
64821
|
setError(err instanceof Error ? err : new Error(String(err)));
|
|
64499
64822
|
}).finally(() => {
|
|
64500
|
-
|
|
64823
|
+
inflight.delete(pageIdx);
|
|
64501
64824
|
setLoadingCount((n2) => n2 - 1);
|
|
64502
64825
|
});
|
|
64503
64826
|
}, [queryClient, apiUrl, repo, workspace, path2, hash2, requestOptions, type, onNotIndexed]);
|
|
@@ -64505,8 +64828,8 @@ const PagedDatasetPreview = memo(function PagedDatasetPreview2({
|
|
|
64505
64828
|
if (totals === null && error3 === null) loadPage(0);
|
|
64506
64829
|
}, [totals, error3, loadPage]);
|
|
64507
64830
|
const onNeedRows = useCallback((startRow, endRow) => {
|
|
64508
|
-
const first2 = Math.max(0, Math.floor(startRow /
|
|
64509
|
-
const last2 = Math.max(first2, Math.ceil(endRow /
|
|
64831
|
+
const first2 = Math.max(0, Math.floor(startRow / pageSize));
|
|
64832
|
+
const last2 = Math.max(first2, Math.ceil(endRow / pageSize) - 1);
|
|
64510
64833
|
const missing = [];
|
|
64511
64834
|
for (let p2 = first2; p2 <= last2; p2++) {
|
|
64512
64835
|
if (!pages.has(p2)) missing.push(p2);
|
|
@@ -64514,7 +64837,7 @@ const PagedDatasetPreview = memo(function PagedDatasetPreview2({
|
|
|
64514
64837
|
pagingDebug(`need rows [${startRow}, ${endRow}) → pages ${first2}..${last2}, missing=[${missing.join(",")}], inflight=[${[...inflightRef.current].join(",")}]`);
|
|
64515
64838
|
setPages((prev2) => pruneRetainedPages(prev2, first2, last2, MAX_RETAINED_PAGES));
|
|
64516
64839
|
for (const p2 of missing) loadPage(p2);
|
|
64517
|
-
}, [pages, loadPage]);
|
|
64840
|
+
}, [pages, loadPage, pageSize]);
|
|
64518
64841
|
const keyType = useMemo(() => type.type === "Dict" ? type.value.key : type.type === "Set" ? type.value : null, [type]);
|
|
64519
64842
|
const pathParts = useMemo(() => path2.split(".").filter(Boolean).map((v3) => variant("field", v3)), [path2]);
|
|
64520
64843
|
const onFindKey = useCallback(async (query) => {
|
|
@@ -64551,11 +64874,11 @@ const PagedDatasetPreview = memo(function PagedDatasetPreview2({
|
|
|
64551
64874
|
}), [type]);
|
|
64552
64875
|
const paging = useMemo(() => totals === null ? null : {
|
|
64553
64876
|
totalRows: totals.elements,
|
|
64554
|
-
pageSize
|
|
64877
|
+
pageSize,
|
|
64555
64878
|
pages,
|
|
64556
64879
|
onNeedRows,
|
|
64557
64880
|
scrollToRow: jumpRow
|
|
64558
|
-
}, [totals, pages, onNeedRows, jumpRow]);
|
|
64881
|
+
}, [totals, pageSize, pages, onNeedRows, jumpRow]);
|
|
64559
64882
|
if (error3 !== null) {
|
|
64560
64883
|
if (error3 instanceof ApiError && error3.code === "dataset_too_large") {
|
|
64561
64884
|
return /* @__PURE__ */ jsxs(Flex, { height: "100%", direction: "column", align: "center", justify: "center", gap: 3, p: 6, children: [
|
|
@@ -64573,11 +64896,11 @@ const PagedDatasetPreview = memo(function PagedDatasetPreview2({
|
|
|
64573
64896
|
return /* @__PURE__ */ jsxs(Flex, { direction: "column", height: "100%", overflow: "hidden", children: [
|
|
64574
64897
|
/* @__PURE__ */ jsxs(Flex, { px: 4, py: 2, gap: 2, align: "center", flexShrink: 0, borderBottom: "1px solid", borderColor: "border.subtle", children: [
|
|
64575
64898
|
/* @__PURE__ */ jsxs(Text, { fontSize: "xs", color: "fg.muted", whiteSpace: "nowrap", children: [
|
|
64576
|
-
totals.elements
|
|
64899
|
+
words.number(totals.elements),
|
|
64577
64900
|
" ",
|
|
64578
64901
|
itemNoun,
|
|
64579
64902
|
" · ",
|
|
64580
|
-
formatSize(totals.bytes > 0 ? totals.bytes : sizeBytes)
|
|
64903
|
+
formatSize(totals.bytes > 0 ? totals.bytes : sizeBytes, words)
|
|
64581
64904
|
] }),
|
|
64582
64905
|
loadingCount > 0 && /* @__PURE__ */ jsx$1(Text, { fontSize: "xs", color: "fg.muted", children: "Loading…" }),
|
|
64583
64906
|
keyType !== null && /* @__PURE__ */ jsx$1(
|
|
@@ -64594,12 +64917,17 @@ const PagedDatasetPreview = memo(function PagedDatasetPreview2({
|
|
|
64594
64917
|
] }),
|
|
64595
64918
|
/* @__PURE__ */ jsx$1(Box, { flex: 1, minHeight: 0, overflow: "hidden", children: /* @__PURE__ */ jsx$1(EastChakraValueTree, { value: treeValue, storageKey: `${path2}:page`, paging }) })
|
|
64596
64919
|
] });
|
|
64597
|
-
}, (prev2, next2) =>
|
|
64920
|
+
}, (prev2, next2) => {
|
|
64921
|
+
var _a2, _b2;
|
|
64922
|
+
return prev2.apiUrl === next2.apiUrl && prev2.repo === next2.repo && prev2.workspace === next2.workspace && prev2.path === next2.path && prev2.hash === next2.hash && prev2.sizeBytes === next2.sizeBytes && ((_a2 = prev2.requestOptions) == null ? void 0 : _a2.token) === ((_b2 = next2.requestOptions) == null ? void 0 : _b2.token);
|
|
64923
|
+
});
|
|
64598
64924
|
const DEFAULT_SIZE_LIMIT = 200 * 1024;
|
|
64599
|
-
|
|
64600
|
-
|
|
64601
|
-
|
|
64602
|
-
|
|
64925
|
+
const KB_FORMAT = variant("number", { minimumFractionDigits: some(1n), maximumFractionDigits: some(1n), signDisplay: none$1 });
|
|
64926
|
+
const MB_FORMAT = variant("number", { minimumFractionDigits: some(2n), maximumFractionDigits: some(2n), signDisplay: none$1 });
|
|
64927
|
+
function formatSize(bytes, words = formatters()) {
|
|
64928
|
+
if (bytes < 1024) return `${words.number(bytes)} B`;
|
|
64929
|
+
if (bytes < 1024 * 1024) return `${words.value(bytes / 1024, KB_FORMAT)} KB`;
|
|
64930
|
+
return `${words.value(bytes / 1024 / 1024, MB_FORMAT)} MB`;
|
|
64603
64931
|
}
|
|
64604
64932
|
function DownloadButton({ onClick, label }) {
|
|
64605
64933
|
const [downloading, setDownloading] = useState(false);
|
|
@@ -64627,6 +64955,7 @@ const DatasetPreview = memo(function DatasetPreview2({
|
|
|
64627
64955
|
editable = false
|
|
64628
64956
|
}) {
|
|
64629
64957
|
var _a2;
|
|
64958
|
+
const words = useFormatters();
|
|
64630
64959
|
const statusQuery = useDatasetStatus(apiUrl, repo, workspace, path2, {
|
|
64631
64960
|
...requestOptions != null && { requestOptions },
|
|
64632
64961
|
...pollInterval !== void 0 && { pollInterval }
|
|
@@ -64654,12 +64983,29 @@ const DatasetPreview = memo(function DatasetPreview2({
|
|
|
64654
64983
|
const setMutation = useDatasetSet(apiUrl, repo, workspace, requestOptions);
|
|
64655
64984
|
const queryClient = useQueryClient();
|
|
64656
64985
|
const decoded = (_a2 = valueQuery.data) == null ? void 0 : _a2.decoded;
|
|
64657
|
-
const
|
|
64658
|
-
|
|
64986
|
+
const edited = useRef(null);
|
|
64987
|
+
const writing = useRef(0);
|
|
64988
|
+
const writes = useRef(Promise.resolve());
|
|
64989
|
+
useEffect(() => {
|
|
64990
|
+
if (writing.current === 0) edited.current = null;
|
|
64991
|
+
}, [decoded]);
|
|
64992
|
+
const write = useCallback((next2) => {
|
|
64993
|
+
if (workspace == null || path2 == null || type === void 0) return Promise.resolve();
|
|
64659
64994
|
const treePath = path2.split(".").filter(Boolean).map((p2) => variant("field", p2));
|
|
64660
64995
|
const data4 = encodeBeast2For(type)(next2);
|
|
64661
|
-
|
|
64662
|
-
|
|
64996
|
+
edited.current = { value: next2 };
|
|
64997
|
+
writing.current++;
|
|
64998
|
+
const run = writes.current.then(async () => {
|
|
64999
|
+
await setMutation.mutateAsync({ path: treePath, data: data4 });
|
|
65000
|
+
await queryClient.invalidateQueries({ queryKey: ["datasetStatus", apiUrl, repo, workspace, path2] });
|
|
65001
|
+
});
|
|
65002
|
+
writes.current = run.catch(() => void 0);
|
|
65003
|
+
return run.catch((err) => {
|
|
65004
|
+
edited.current = null;
|
|
65005
|
+
throw err;
|
|
65006
|
+
}).finally(() => {
|
|
65007
|
+
writing.current--;
|
|
65008
|
+
});
|
|
64663
65009
|
}, [apiUrl, repo, workspace, path2, type, setMutation, queryClient]);
|
|
64664
65010
|
const keyType = useMemo(() => type === void 0 ? null : type.type === "Dict" ? type.value.key : type.type === "Set" ? type.value : null, [type]);
|
|
64665
65011
|
const inlineKeys = useMemo(() => decoded === void 0 || type === void 0 ? null : type.type === "Dict" ? [...decoded.keys()] : type.type === "Set" ? [...decoded.values()] : null, [type, decoded]);
|
|
@@ -64695,11 +65041,12 @@ const DatasetPreview = memo(function DatasetPreview2({
|
|
|
64695
65041
|
const treeValue = useMemo(() => {
|
|
64696
65042
|
if (type === void 0 || decoded === void 0) return null;
|
|
64697
65043
|
const root2 = ValueTree.materialize(type, decoded);
|
|
65044
|
+
const base = () => edited.current !== null ? edited.current.value : decoded;
|
|
64698
65045
|
const wire = editable ? {
|
|
64699
|
-
onEdit: some((p2, leaf) => write(ValueTree.applyEdit(type,
|
|
64700
|
-
onInsert: some((p2) => write(ValueTree.applyEdit(type,
|
|
64701
|
-
onRemove: some((p2) => write(ValueTree.applyEdit(type,
|
|
64702
|
-
onTag: some((p2, tag) => write(ValueTree.applyEdit(type,
|
|
65046
|
+
onEdit: some((p2, leaf) => write(ValueTree.applyEdit(type, base(), p2, { kind: "edit", leaf }))),
|
|
65047
|
+
onInsert: some((p2) => write(ValueTree.applyEdit(type, base(), p2, { kind: "insert" }))),
|
|
65048
|
+
onRemove: some((p2) => write(ValueTree.applyEdit(type, base(), p2, { kind: "remove" }))),
|
|
65049
|
+
onTag: some((p2, tag) => write(ValueTree.applyEdit(type, base(), p2, { kind: "tag", tag })))
|
|
64703
65050
|
} : { onEdit: none$1, onInsert: none$1, onRemove: none$1, onTag: none$1 };
|
|
64704
65051
|
return { root: root2, ...wire, style: some({ height: some("100%"), maxHeight: none$1, openDepth: none$1, toolbar: some(true) }) };
|
|
64705
65052
|
}, [type, decoded, editable, write]);
|
|
@@ -64733,18 +65080,21 @@ const DatasetPreview = memo(function DatasetPreview2({
|
|
|
64733
65080
|
/* @__PURE__ */ jsx$1(Text, { fontSize: "lg", color: "fg.warning", fontWeight: "bold", children: "Value too large to display" }),
|
|
64734
65081
|
/* @__PURE__ */ jsxs(Text, { color: "fg.muted", fontSize: "sm", children: [
|
|
64735
65082
|
"The data is ",
|
|
64736
|
-
formatSize(sizeBytes),
|
|
65083
|
+
formatSize(sizeBytes, words),
|
|
64737
65084
|
", which exceeds the ",
|
|
64738
|
-
formatSize(sizeLimit),
|
|
65085
|
+
formatSize(sizeLimit, words),
|
|
64739
65086
|
" display limit."
|
|
64740
65087
|
] }),
|
|
64741
65088
|
/* @__PURE__ */ jsx$1(DownloadButton, { onClick: download, label: "Download value" })
|
|
64742
65089
|
] });
|
|
64743
65090
|
}
|
|
65091
|
+
if (valueQuery.error) {
|
|
65092
|
+
const { message, details } = formatApiError(valueQuery.error);
|
|
65093
|
+
return /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "error", title: "Load failed", message, details: details ?? formatError(valueQuery.error) });
|
|
65094
|
+
}
|
|
64744
65095
|
if (valueQuery.isLoading || !valueQuery.data) return /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "loading", title: "Loading..." });
|
|
64745
|
-
if (valueQuery.error) return /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "error", title: "Decode failed", message: valueQuery.error.message });
|
|
64746
65096
|
const count = type === void 0 || decoded === void 0 ? null : type.type === "Array" ? decoded.length : type.type === "Set" || type.type === "Dict" ? decoded.size : null;
|
|
64747
|
-
const countText = count === null ? "" : `${
|
|
65097
|
+
const countText = count === null ? "" : `${words.number(count)} ${(type == null ? void 0 : type.type) === "Dict" ? "entries" : "items"} · `;
|
|
64748
65098
|
return /* @__PURE__ */ jsxs(Flex, { direction: "column", height: "100%", overflow: "hidden", children: [
|
|
64749
65099
|
/* @__PURE__ */ jsxs(Flex, { px: 4, py: 2, gap: 2, align: "center", flexShrink: 0, borderBottom: "1px solid", borderColor: "border.subtle", children: [
|
|
64750
65100
|
keyType !== null && inlineKeys !== null && /* @__PURE__ */ jsx$1(
|
|
@@ -64760,7 +65110,7 @@ const DatasetPreview = memo(function DatasetPreview2({
|
|
|
64760
65110
|
/* @__PURE__ */ jsxs(Flex, { flex: 1, justify: "flex-end", align: "center", gap: 2, children: [
|
|
64761
65111
|
/* @__PURE__ */ jsxs(Text, { fontSize: "xs", color: "fg.muted", children: [
|
|
64762
65112
|
countText,
|
|
64763
|
-
formatSize(sizeBytes)
|
|
65113
|
+
formatSize(sizeBytes, words)
|
|
64764
65114
|
] }),
|
|
64765
65115
|
/* @__PURE__ */ jsx$1(DownloadButton, { onClick: download })
|
|
64766
65116
|
] })
|
|
@@ -64813,19 +65163,15 @@ const UITaskPreview = memo(function UITaskPreview2({
|
|
|
64813
65163
|
const workspace = (config2 == null ? void 0 : config2.workspace) ?? (e3 == null ? void 0 : e3.workspace) ?? null;
|
|
64814
65164
|
const token2 = (config2 == null ? void 0 : config2.token) ?? (e3 == null ? void 0 : e3.token) ?? null;
|
|
64815
65165
|
const requestOptions = { token: token2 };
|
|
65166
|
+
const bound3 = cache3 == null ? void 0 : cache3.getConfig().workspace;
|
|
65167
|
+
const foreign = (config2 == null ? void 0 : config2.workspace) !== void 0 && bound3 !== void 0 && config2.workspace !== bound3;
|
|
64816
65168
|
const detailsQuery = useTaskDetails(apiUrl ?? "", repo, workspace, task, { requestOptions });
|
|
64817
65169
|
const details = detailsQuery.data;
|
|
64818
|
-
const
|
|
64819
|
-
const
|
|
64820
|
-
const manifest = useMemo(() => {
|
|
64821
|
-
if (!details || !isUI) return null;
|
|
64822
|
-
const meta3 = getTaskMetadata(details);
|
|
64823
|
-
return meta3 ? decodeManifest(meta3) : { paths: [], functions: [], records: [], pages: [] };
|
|
64824
|
-
}, [details, isUI]);
|
|
64825
|
-
const outputPath = details ? treePathToString$1(details.output) : null;
|
|
65170
|
+
const manifest = useMemo(() => (details == null ? void 0 : details.role.type) === "ui" ? details.role.value : null, [details]);
|
|
65171
|
+
const outputPath = details ? treePathToString$1(details.output.path) : null;
|
|
64826
65172
|
const preloads = useMemo(
|
|
64827
|
-
() => manifest && workspace ? manifest.paths.map((path2) => ({ workspace, path: path2 })) : [],
|
|
64828
|
-
[manifest, workspace]
|
|
65173
|
+
() => manifest && workspace && !foreign ? manifest.paths.map((path2) => ({ workspace, path: path2 })) : [],
|
|
65174
|
+
[manifest, workspace, foreign]
|
|
64829
65175
|
);
|
|
64830
65176
|
const { loading: preloading, error: preloadError } = usePreloadReactiveDatasets(preloads);
|
|
64831
65177
|
const scopedPlatforms = useMemo(
|
|
@@ -64851,7 +65197,7 @@ const UITaskPreview = memo(function UITaskPreview2({
|
|
|
64851
65197
|
[manifest]
|
|
64852
65198
|
);
|
|
64853
65199
|
useEffect(() => {
|
|
64854
|
-
if (!cache3 || !manifest || !workspace) return;
|
|
65200
|
+
if (!cache3 || !manifest || !workspace || foreign) return;
|
|
64855
65201
|
for (const path2 of manifest.paths) {
|
|
64856
65202
|
cache3.setRefetchInterval(workspace, path2, pollInterval);
|
|
64857
65203
|
}
|
|
@@ -64860,7 +65206,7 @@ const UITaskPreview = memo(function UITaskPreview2({
|
|
|
64860
65206
|
cache3.clearRefetchInterval(workspace, path2);
|
|
64861
65207
|
}
|
|
64862
65208
|
};
|
|
64863
|
-
}, [cache3, manifest, workspace, pollInterval]);
|
|
65209
|
+
}, [cache3, manifest, workspace, pollInterval, foreign]);
|
|
64864
65210
|
const statusQuery = useDatasetStatus(apiUrl ?? "", repo, workspace, outputPath, { requestOptions });
|
|
64865
65211
|
const valueQuery = useDatasetValue(apiUrl ?? "", repo, workspace, outputPath, {
|
|
64866
65212
|
requestOptions,
|
|
@@ -64870,16 +65216,20 @@ const UITaskPreview = memo(function UITaskPreview2({
|
|
|
64870
65216
|
});
|
|
64871
65217
|
const store = useMemo(() => createUIStore(), [task]);
|
|
64872
65218
|
if (!apiUrl) return /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "error", title: "Configuration error", message: "No apiUrl available — render UITaskPreview inside an <E3Provider> or pass a config prop." });
|
|
65219
|
+
if (foreign) {
|
|
65220
|
+
return /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "error", title: "Workspace mismatch", message: `config names workspace "${config2 == null ? void 0 : config2.workspace}", and the data bindings read workspace "${bound3}", the one the surrounding <ReactiveDatasetProvider> serves: a page previews one workspace.` });
|
|
65221
|
+
}
|
|
64873
65222
|
if (detailsQuery.isLoading) return /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "loading", title: "Loading task..." });
|
|
64874
65223
|
if (detailsQuery.error) return /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "error", title: "Error", message: detailsQuery.error.message });
|
|
64875
65224
|
if (!details) return /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "info", title: "No task", message: `Task "${task}" not found` });
|
|
64876
|
-
if (!
|
|
65225
|
+
if (!manifest) return /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "error", title: "Not a UI task", message: `Task "${task}" is a ${details.role.type} task` });
|
|
64877
65226
|
if (preloadError) return /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "error", title: "Preload failed", message: preloadError.message });
|
|
64878
65227
|
if (preloading) return /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "loading", title: "Loading datasets..." });
|
|
65228
|
+
if (statusQuery.error) return /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "error", title: "Error", message: statusQuery.error.message });
|
|
64879
65229
|
if (statusQuery.isLoading || !statusQuery.data) return /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "loading", title: "Loading..." });
|
|
64880
65230
|
if (statusQuery.data.refType !== "value") return /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "info", title: "No output yet", message: "Task has not produced a value" });
|
|
65231
|
+
if (valueQuery.error) return /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "error", title: "Load failed", message: valueQuery.error.message });
|
|
64881
65232
|
if (valueQuery.isLoading || !valueQuery.data) return /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "loading", title: "Loading..." });
|
|
64882
|
-
if (valueQuery.error) return /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "error", title: "Decode failed", message: valueQuery.error.message });
|
|
64883
65233
|
return /* @__PURE__ */ jsx$1(UIStoreProvider, { store, children: /* @__PURE__ */ jsx$1(ErrorBoundary, { children: /* @__PURE__ */ jsx$1(Box, { height: "100%", overflow: bare ? void 0 : "auto", p: bare ? void 0 : "4", minH: bare ? 0 : void 0, children: /* @__PURE__ */ jsx$1(
|
|
64884
65234
|
EastChakraComponent,
|
|
64885
65235
|
{
|
|
@@ -65336,7 +65686,7 @@ const DataTaskPreview = memo(function DataTaskPreview2({
|
|
|
65336
65686
|
const detailsQuery = useTaskDetails(apiUrl, repo, workspace, task, {
|
|
65337
65687
|
...requestOptions != null && { requestOptions }
|
|
65338
65688
|
});
|
|
65339
|
-
const outputPath = detailsQuery.data ? treePathToString(detailsQuery.data.output) : null;
|
|
65689
|
+
const outputPath = detailsQuery.data ? treePathToString(detailsQuery.data.output.path) : null;
|
|
65340
65690
|
return /* @__PURE__ */ jsxs(Box, { height: "100%", display: "flex", flexDirection: "column", overflow: "hidden", children: [
|
|
65341
65691
|
/* @__PURE__ */ jsx$1(
|
|
65342
65692
|
Flex,
|
|
@@ -65400,13 +65750,14 @@ const TaskPreview = memo(function TaskPreview2({
|
|
|
65400
65750
|
requestOptions,
|
|
65401
65751
|
bare = false
|
|
65402
65752
|
}) {
|
|
65753
|
+
var _a2;
|
|
65403
65754
|
const detailsQuery = useTaskDetails(apiUrl, repo, workspace, task, {
|
|
65404
65755
|
...requestOptions != null && { requestOptions }
|
|
65405
65756
|
});
|
|
65406
|
-
const
|
|
65757
|
+
const isUI = ((_a2 = detailsQuery.data) == null ? void 0 : _a2.role.type) === "ui";
|
|
65407
65758
|
return /* @__PURE__ */ jsxs(Box, { height: "100%", display: "flex", flexDirection: "column", overflow: "hidden", children: [
|
|
65408
65759
|
!bare && /* @__PURE__ */ jsx$1(Flex, { px: 4, py: 2, borderBottom: "1px solid", borderColor: "border.subtle", bg: "bg.surface", align: "center", flexShrink: 0, children: /* @__PURE__ */ jsx$1(Text, { fontSize: "sm", fontWeight: "medium", color: "fg", children: task }) }),
|
|
65409
|
-
/* @__PURE__ */ jsx$1(Box, { flex: 1, overflow: "hidden", minHeight: 0, children: detailsQuery.isLoading ? /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "loading", title: "Loading task..." }) : detailsQuery.error ? /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "error", title: "Error", message: detailsQuery.error.message }) :
|
|
65760
|
+
/* @__PURE__ */ jsx$1(Box, { flex: 1, overflow: "hidden", minHeight: 0, children: detailsQuery.isLoading ? /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "loading", title: "Loading task..." }) : detailsQuery.error ? /* @__PURE__ */ jsx$1(StatusDisplay, { variant: "error", title: "Error", message: detailsQuery.error.message }) : isUI ? /* @__PURE__ */ jsx$1(
|
|
65410
65761
|
UITaskPreview,
|
|
65411
65762
|
{
|
|
65412
65763
|
task,
|
|
@@ -65424,33 +65775,16 @@ const TaskPreview = memo(function TaskPreview2({
|
|
|
65424
65775
|
}
|
|
65425
65776
|
) })
|
|
65426
65777
|
] });
|
|
65427
|
-
}, (prev2, next2) =>
|
|
65778
|
+
}, (prev2, next2) => {
|
|
65779
|
+
var _a2, _b2;
|
|
65780
|
+
return prev2.task === next2.task && prev2.apiUrl === next2.apiUrl && prev2.repo === next2.repo && prev2.workspace === next2.workspace && prev2.bare === next2.bare && ((_a2 = prev2.requestOptions) == null ? void 0 : _a2.token) === ((_b2 = next2.requestOptions) == null ? void 0 : _b2.token);
|
|
65781
|
+
});
|
|
65428
65782
|
function formatPrimitive(type, value) {
|
|
65429
|
-
|
|
65430
|
-
|
|
65431
|
-
return "null";
|
|
65432
|
-
case "Boolean":
|
|
65433
|
-
return value ? "true" : "false";
|
|
65434
|
-
case "Integer":
|
|
65435
|
-
return String(value);
|
|
65436
|
-
case "Float": {
|
|
65437
|
-
const num2 = value;
|
|
65438
|
-
if (Number.isNaN(num2)) return "NaN";
|
|
65439
|
-
if (!Number.isFinite(num2)) return num2 > 0 ? "Infinity" : "-Infinity";
|
|
65440
|
-
return String(num2);
|
|
65441
|
-
}
|
|
65442
|
-
case "String":
|
|
65443
|
-
return `"${value}"`;
|
|
65444
|
-
case "DateTime":
|
|
65445
|
-
return value.toISOString();
|
|
65446
|
-
case "Blob":
|
|
65447
|
-
return `Blob[${value.length} bytes]`;
|
|
65448
|
-
default:
|
|
65449
|
-
return String(value);
|
|
65450
|
-
}
|
|
65783
|
+
if (type.type === "Blob") return `Blob[${value.length} bytes]`;
|
|
65784
|
+
return printFor(type)(value);
|
|
65451
65785
|
}
|
|
65452
65786
|
function isPrimitive(type) {
|
|
65453
|
-
return ["Null", "Boolean", "Integer", "Float", "String", "DateTime", "Blob"
|
|
65787
|
+
return ["Null", "Boolean", "Integer", "Float", "String", "DateTime", "Blob"].includes(type.type);
|
|
65454
65788
|
}
|
|
65455
65789
|
function getTypeLabel(type, value) {
|
|
65456
65790
|
switch (type.type) {
|
|
@@ -65572,8 +65906,8 @@ function ValueNode({
|
|
|
65572
65906
|
}
|
|
65573
65907
|
if (type.type === "Variant") {
|
|
65574
65908
|
const cases = type.value;
|
|
65575
|
-
const
|
|
65576
|
-
const activeCase = cases.find((c2) => c2.name ===
|
|
65909
|
+
const chosen = value;
|
|
65910
|
+
const activeCase = cases.find((c2) => c2.name === chosen.type);
|
|
65577
65911
|
if (!activeCase) {
|
|
65578
65912
|
return /* @__PURE__ */ jsxs(Box, { py: 0.5, display: "flex", alignItems: "center", gap: 2, children: [
|
|
65579
65913
|
label && /* @__PURE__ */ jsxs(Text, { as: "span", color: "accent.purple", fontWeight: "medium", children: [
|
|
@@ -65582,7 +65916,7 @@ function ValueNode({
|
|
|
65582
65916
|
] }),
|
|
65583
65917
|
/* @__PURE__ */ jsxs(Text, { as: "span", color: "fg.danger", children: [
|
|
65584
65918
|
"Unknown variant: ",
|
|
65585
|
-
|
|
65919
|
+
chosen.type
|
|
65586
65920
|
] })
|
|
65587
65921
|
] });
|
|
65588
65922
|
}
|
|
@@ -65594,7 +65928,7 @@ function ValueNode({
|
|
|
65594
65928
|
] }),
|
|
65595
65929
|
/* @__PURE__ */ jsxs(Badge, { size: "xs", colorPalette: "brand", variant: "subtle", children: [
|
|
65596
65930
|
".",
|
|
65597
|
-
|
|
65931
|
+
chosen.type
|
|
65598
65932
|
] })
|
|
65599
65933
|
] });
|
|
65600
65934
|
}
|
|
@@ -65606,14 +65940,14 @@ function ValueNode({
|
|
|
65606
65940
|
] }),
|
|
65607
65941
|
/* @__PURE__ */ jsxs(Badge, { size: "xs", colorPalette: "brand", variant: "subtle", children: [
|
|
65608
65942
|
".",
|
|
65609
|
-
|
|
65943
|
+
chosen.type
|
|
65610
65944
|
] })
|
|
65611
65945
|
] }),
|
|
65612
65946
|
/* @__PURE__ */ jsx$1(Box, { pl: 4, children: /* @__PURE__ */ jsx$1(
|
|
65613
65947
|
ValueNode,
|
|
65614
65948
|
{
|
|
65615
65949
|
type: activeCase.type,
|
|
65616
|
-
value:
|
|
65950
|
+
value: chosen.value,
|
|
65617
65951
|
depth: depth + 1
|
|
65618
65952
|
}
|
|
65619
65953
|
) })
|
|
@@ -65819,8 +66153,6 @@ export {
|
|
|
65819
66153
|
getBindingTypes,
|
|
65820
66154
|
getReactiveDatasetCache,
|
|
65821
66155
|
getStagedStore,
|
|
65822
|
-
getTaskKind,
|
|
65823
|
-
getTaskMetadata,
|
|
65824
66156
|
initializeFunctionApi,
|
|
65825
66157
|
initializePagedApi,
|
|
65826
66158
|
initializeReactiveDatasetCache,
|
|
@@ -65828,6 +66160,7 @@ export {
|
|
|
65828
66160
|
initializeStagedStore,
|
|
65829
66161
|
isBindingTracking,
|
|
65830
66162
|
onWriteError,
|
|
66163
|
+
pagedRevisionKey,
|
|
65831
66164
|
pagedTotalKey,
|
|
65832
66165
|
pagedWindowKey,
|
|
65833
66166
|
preloadReactiveDatasetList,
|