@sanity/sdk 2.8.0 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks-dts/utils.d.ts +2450 -0
- package/dist/_chunks-es/_internal.js +129 -0
- package/dist/_chunks-es/_internal.js.map +1 -0
- package/dist/_chunks-es/createGroqSearchFilter.js +1537 -0
- package/dist/_chunks-es/createGroqSearchFilter.js.map +1 -0
- package/dist/_chunks-es/telemetryManager.js +87 -0
- package/dist/_chunks-es/telemetryManager.js.map +1 -0
- package/dist/_chunks-es/version.js +7 -0
- package/dist/_chunks-es/version.js.map +1 -0
- package/dist/_exports/_internal.d.ts +64 -0
- package/dist/_exports/_internal.js +20 -0
- package/dist/_exports/_internal.js.map +1 -0
- package/dist/index.d.ts +2 -2343
- package/dist/index.js +465 -1813
- package/dist/index.js.map +1 -1
- package/package.json +17 -12
- package/src/_exports/_internal.ts +14 -0
- package/src/_exports/index.ts +18 -1
- package/src/auth/authStore.test.ts +150 -1
- package/src/auth/authStore.ts +11 -11
- package/src/auth/dashboardAuth.ts +2 -2
- package/src/auth/handleAuthCallback.ts +9 -3
- package/src/auth/logout.test.ts +1 -1
- package/src/auth/logout.ts +1 -1
- package/src/auth/refreshStampedToken.test.ts +118 -1
- package/src/auth/refreshStampedToken.ts +3 -2
- package/src/auth/standaloneAuth.ts +9 -3
- package/src/auth/studioAuth.ts +34 -7
- package/src/auth/studioModeAuth.ts +2 -1
- package/src/auth/subscribeToStateAndFetchCurrentUser.test.ts +10 -2
- package/src/auth/subscribeToStateAndFetchCurrentUser.ts +5 -1
- package/src/auth/subscribeToStorageEventsAndSetToken.ts +2 -2
- package/src/auth/utils.ts +33 -0
- package/src/client/clientStore.test.ts +44 -30
- package/src/client/clientStore.ts +49 -48
- package/src/comlink/controller/actions/getOrCreateChannel.ts +2 -2
- package/src/comlink/node/actions/getOrCreateNode.ts +2 -2
- package/src/comlink/node/getNodeState.ts +2 -1
- package/src/config/sanityConfig.ts +78 -12
- package/src/document/actions.ts +18 -11
- package/src/document/applyDocumentActions.test.ts +7 -6
- package/src/document/applyDocumentActions.ts +10 -4
- package/src/document/documentStore.test.ts +542 -188
- package/src/document/documentStore.ts +142 -76
- package/src/document/events.ts +7 -2
- package/src/document/permissions.test.ts +18 -16
- package/src/document/permissions.ts +35 -11
- package/src/document/processActions.test.ts +359 -32
- package/src/document/processActions.ts +106 -78
- package/src/document/reducers.test.ts +117 -29
- package/src/document/reducers.ts +47 -40
- package/src/document/sharedListener.ts +16 -6
- package/src/document/util.ts +14 -0
- package/src/favorites/favorites.test.ts +9 -2
- package/src/presence/bifurTransport.test.ts +46 -6
- package/src/presence/bifurTransport.ts +19 -2
- package/src/presence/presenceStore.test.ts +96 -0
- package/src/presence/presenceStore.ts +96 -24
- package/src/preview/getPreviewState.test.ts +115 -98
- package/src/preview/getPreviewState.ts +38 -60
- package/src/preview/previewProjectionUtils.test.ts +179 -0
- package/src/preview/previewProjectionUtils.ts +93 -0
- package/src/preview/resolvePreview.test.ts +42 -25
- package/src/preview/resolvePreview.ts +33 -10
- package/src/preview/{previewStore.ts → types.ts} +8 -17
- package/src/projection/getProjectionState.test.ts +16 -16
- package/src/projection/getProjectionState.ts +6 -5
- package/src/projection/projectionQuery.ts +2 -3
- package/src/projection/projectionStore.test.ts +2 -2
- package/src/projection/resolveProjection.ts +2 -2
- package/src/projection/subscribeToStateAndFetchBatches.test.ts +1 -1
- package/src/projection/subscribeToStateAndFetchBatches.ts +12 -11
- package/src/projection/types.ts +1 -1
- package/src/query/queryStore.test.ts +12 -12
- package/src/query/queryStore.ts +12 -11
- package/src/query/reducers.ts +3 -3
- package/src/releases/getPerspectiveState.ts +7 -6
- package/src/releases/releasesStore.test.ts +20 -5
- package/src/releases/releasesStore.ts +20 -8
- package/src/store/createActionBinder.test.ts +31 -31
- package/src/store/createActionBinder.ts +43 -38
- package/src/store/createSanityInstance.ts +2 -3
- package/src/store/createStateSourceAction.test.ts +62 -0
- package/src/store/createStateSourceAction.ts +34 -39
- package/src/telemetry/__telemetry__/sdk.telemetry.ts +42 -0
- package/src/telemetry/devMode.test.ts +52 -0
- package/src/telemetry/devMode.ts +40 -0
- package/src/telemetry/initTelemetry.test.ts +225 -0
- package/src/telemetry/initTelemetry.ts +205 -0
- package/src/telemetry/telemetryManager.test.ts +263 -0
- package/src/telemetry/telemetryManager.ts +187 -0
- package/src/users/reducers.ts +3 -4
- package/src/users/usersStore.test.ts +1 -0
- package/src/users/usersStore.ts +5 -1
- package/src/utils/createFetcherStore.test.ts +6 -4
- package/src/utils/createFetcherStore.ts +8 -5
- package/src/utils/getStagingApiHost.test.ts +21 -0
- package/src/utils/getStagingApiHost.ts +14 -0
- package/src/utils/ids.test.ts +1 -29
- package/src/utils/ids.ts +0 -10
- package/src/utils/isImportError.test.ts +72 -0
- package/src/utils/isImportError.ts +34 -0
- package/src/utils/object.test.ts +95 -0
- package/src/utils/object.ts +142 -0
- package/src/utils/setCleanupTimeout.ts +24 -0
- package/src/preview/previewQuery.test.ts +0 -236
- package/src/preview/previewQuery.ts +0 -153
- package/src/preview/previewStore.test.ts +0 -36
- package/src/preview/subscribeToStateAndFetchBatches.test.ts +0 -221
- package/src/preview/subscribeToStateAndFetchBatches.ts +0 -112
- package/src/preview/util.ts +0 -13
package/dist/index.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { createStore } from "zustand/vanilla";
|
|
6
|
-
import { first, switchMap as switchMap$1, groupBy, mergeMap, startWith, pairwise, filter as filter$1, map as map$1, delay, tap, catchError, scan, share as share$1 } from "rxjs/operators";
|
|
1
|
+
import { switchMap, from, firstValueFrom, EMPTY, asapScheduler, distinctUntilChanged, map as map$1, combineLatest, of, concatMap, withLatestFrom, filter as filter$1, concat, timer, throwError, first as first$1, Subject, takeUntil, share, partition, merge, shareReplay, tap as tap$1, catchError as catchError$1, startWith as startWith$1, pairwise as pairwise$1, groupBy as groupBy$1, mergeMap as mergeMap$1, throttle, race, skip, Observable, NEVER, fromEvent, Subscription, debounceTime, defer } from "rxjs";
|
|
2
|
+
import { createLogger, pickProperties, insecureRandomId, getClientState, bindActionGlobally, createStateSourceAction, setCleanupTimeout, omitProperty, defineStore, authStore, AuthStateType, getCleanedUrl, getTokenFromLocation, createLoggedInAuthState, getAuthCode, REQUEST_TAG_PREFIX, DEFAULT_API_VERSION, getDefaultLocation, isDeepEqual, configureLogging as configureLogging$1, isReleasePerspective, isDatasetResource, bindActionByResource, isMediaLibraryResource, isCanvasResource, getUsersKey, addSubscription, parseUsersKey, getClient, PROJECT_API_VERSION, setUsersError, setUsersData, API_VERSION as API_VERSION$6, getDashboardOrganizationId as getDashboardOrganizationId$1, USERS_STATE_CLEAR_DELAY, removeSubscription, updateLastLoadMoreRequest, cancelRequest, initializeRequest, getTokenState, getQueryState, resolveQuery, bindActionByResourceAndPerspective, PREVIEW_PROJECTION, transformProjectionToPreview } from "./_chunks-es/createGroqSearchFilter.js";
|
|
3
|
+
import { createGroqSearchFilter, getActiveReleasesState, getAuthState, getClientErrorApiBody, getClientErrorApiDescription, getClientErrorApiType, getCurrentUserState, getIsInDashboardState, getLoginUrlState, getPerspectiveState, getQueryKey, isCanvasSource, isDatasetSource, isMediaLibrarySource, isProjectUserNotFoundClientError, isStudioConfig, parseQueryKey, setAuthToken } from "./_chunks-es/createGroqSearchFilter.js";
|
|
4
|
+
import { first, switchMap as switchMap$1, groupBy, mergeMap, startWith, pairwise, filter, map, delay, tap, catchError, scan, share as share$1 } from "rxjs/operators";
|
|
7
5
|
import { createController, createNode } from "@sanity/comlink";
|
|
8
6
|
import { createSelector } from "reselect";
|
|
9
7
|
import { SanityEncoder } from "@sanity/mutate";
|
|
10
|
-
import {
|
|
8
|
+
import { getVersionId, DocumentId, getPublishedId, getDraftId, isDraftId, isVersionId, isPublishedId } from "@sanity/id-utils";
|
|
11
9
|
import { jsonMatch, stringifyPath, slicePath, getIndexForKey } from "@sanity/json-match";
|
|
12
10
|
import { getIndexForKey as getIndexForKey2, getPathDepth, joinPaths, jsonMatch as jsonMatch2, slicePath as slicePath2, stringifyPath as stringifyPath2 } from "@sanity/json-match";
|
|
13
11
|
import { evaluateSync, parse } from "groq-js";
|
|
@@ -17,142 +15,8 @@ import { isKeySegment, isKeyedObject } from "@sanity/types";
|
|
|
17
15
|
import { createDocumentLoaderFromClient } from "@sanity/mutate/_unstable_store";
|
|
18
16
|
import { SDK_CHANNEL_NAME, SDK_NODE_NAME } from "@sanity/message-protocol";
|
|
19
17
|
import { fromUrl } from "@sanity/bifur-client";
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
return "projectId" in source && "dataset" in source;
|
|
23
|
-
}
|
|
24
|
-
function isMediaLibrarySource(source) {
|
|
25
|
-
return "mediaLibraryId" in source;
|
|
26
|
-
}
|
|
27
|
-
function isCanvasSource(source) {
|
|
28
|
-
return "canvasId" in source;
|
|
29
|
-
}
|
|
30
|
-
const isReleasePerspective = (perspective) => typeof perspective == "object" && perspective !== null && "releaseName" in perspective;
|
|
31
|
-
function getPublishedId(id) {
|
|
32
|
-
const draftsPrefix = "drafts.";
|
|
33
|
-
return id.startsWith(draftsPrefix) ? id.slice(draftsPrefix.length) : id;
|
|
34
|
-
}
|
|
35
|
-
function getDraftId(id) {
|
|
36
|
-
const draftsPrefix = "drafts.";
|
|
37
|
-
return id.startsWith(draftsPrefix) ? id : `${draftsPrefix}${id}`;
|
|
38
|
-
}
|
|
39
|
-
function insecureRandomId() {
|
|
40
|
-
return Array.from({ length: 16 }, () => Math.floor(Math.random() * 16).toString(16)).join("");
|
|
41
|
-
}
|
|
42
|
-
const LOG_LEVEL_PRIORITY = {
|
|
43
|
-
error: 0,
|
|
44
|
-
warn: 1,
|
|
45
|
-
info: 2,
|
|
46
|
-
debug: 3,
|
|
47
|
-
trace: 4
|
|
48
|
-
}, DEFAULT_CONFIG = {
|
|
49
|
-
level: "warn",
|
|
50
|
-
namespaces: [],
|
|
51
|
-
internal: !1,
|
|
52
|
-
timestamps: !0,
|
|
53
|
-
enableInProduction: !1,
|
|
54
|
-
handler: {
|
|
55
|
-
// eslint-disable-next-line no-console
|
|
56
|
-
error: console.error.bind(console),
|
|
57
|
-
// eslint-disable-next-line no-console
|
|
58
|
-
warn: console.warn.bind(console),
|
|
59
|
-
// eslint-disable-next-line no-console
|
|
60
|
-
info: console.info.bind(console),
|
|
61
|
-
// eslint-disable-next-line no-console
|
|
62
|
-
debug: console.debug.bind(console),
|
|
63
|
-
// eslint-disable-next-line no-console
|
|
64
|
-
trace: console.debug.bind(console)
|
|
65
|
-
// trace uses console.debug
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
function parseDebugEnvVar() {
|
|
69
|
-
if (typeof process > "u" || !process.env?.DEBUG)
|
|
70
|
-
return null;
|
|
71
|
-
const debug = process.env.DEBUG;
|
|
72
|
-
if (!debug.includes("sanity"))
|
|
73
|
-
return null;
|
|
74
|
-
const config = {}, levelMatch = debug.match(/sanity:(trace|debug|info|warn|error):/), hasLevelSpecifier = !!levelMatch;
|
|
75
|
-
if (levelMatch ? config.level = levelMatch[1] : config.level = "debug", debug === "sanity")
|
|
76
|
-
config.namespaces = ["*"];
|
|
77
|
-
else if (hasLevelSpecifier && debug.match(/sanity:(trace|debug|info|warn|error):\*/))
|
|
78
|
-
config.namespaces = ["*"];
|
|
79
|
-
else if (!hasLevelSpecifier && debug.includes("sanity:*"))
|
|
80
|
-
config.namespaces = ["*"];
|
|
81
|
-
else {
|
|
82
|
-
const namespaces = debug.split(",").filter((s) => s.includes("sanity:")).map((s) => {
|
|
83
|
-
const cleaned = s.replace(/^sanity:/, "");
|
|
84
|
-
return hasLevelSpecifier && cleaned.match(/^(trace|debug|info|warn|error):/) ? cleaned.split(":").slice(1).join(":") : cleaned.split(":")[0];
|
|
85
|
-
}).filter(Boolean).filter((ns) => ns !== "*");
|
|
86
|
-
namespaces.length > 0 && (config.namespaces = namespaces);
|
|
87
|
-
}
|
|
88
|
-
return debug.includes(":internal") && (config.internal = !0), config;
|
|
89
|
-
}
|
|
90
|
-
const envConfig = parseDebugEnvVar();
|
|
91
|
-
let globalConfig = {
|
|
92
|
-
...DEFAULT_CONFIG,
|
|
93
|
-
...envConfig ?? {}
|
|
94
|
-
};
|
|
95
|
-
envConfig && (["info", "debug", "trace"].includes(globalConfig.level) || globalConfig.level === "warn") && console.info(
|
|
96
|
-
`[${(/* @__PURE__ */ new Date()).toISOString()}] [INFO] [sdk] Logging auto-configured from DEBUG environment variable`,
|
|
97
|
-
{
|
|
98
|
-
level: globalConfig.level,
|
|
99
|
-
namespaces: globalConfig.namespaces,
|
|
100
|
-
internal: globalConfig.internal,
|
|
101
|
-
source: "env:DEBUG",
|
|
102
|
-
value: typeof process < "u" ? process.env?.DEBUG : void 0
|
|
103
|
-
}
|
|
104
|
-
);
|
|
105
|
-
function configureLogging$1(config) {
|
|
106
|
-
globalConfig = {
|
|
107
|
-
...globalConfig,
|
|
108
|
-
...config,
|
|
109
|
-
handler: config.handler ?? globalConfig.handler
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
function isLoggingEnabled() {
|
|
113
|
-
return typeof process < "u" && process.env?.NODE_ENV === "production" ? globalConfig.enableInProduction : !0;
|
|
114
|
-
}
|
|
115
|
-
function isNamespaceEnabled(namespace) {
|
|
116
|
-
return isLoggingEnabled() ? globalConfig.namespaces.includes("*") ? !0 : globalConfig.namespaces.includes(namespace) : !1;
|
|
117
|
-
}
|
|
118
|
-
function isLevelEnabled(level) {
|
|
119
|
-
return isLoggingEnabled() ? LOG_LEVEL_PRIORITY[level] <= LOG_LEVEL_PRIORITY[globalConfig.level] : !1;
|
|
120
|
-
}
|
|
121
|
-
function formatMessage(namespace, level, message, context) {
|
|
122
|
-
const parts = [];
|
|
123
|
-
if (globalConfig.timestamps) {
|
|
124
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
125
|
-
parts.push(`[${timestamp}]`);
|
|
126
|
-
}
|
|
127
|
-
parts.push(`[${level.toUpperCase()}]`), parts.push(`[${namespace}]`);
|
|
128
|
-
const instanceContext = context?.instanceContext;
|
|
129
|
-
return instanceContext && (instanceContext.projectId && parts.push(`[project:${instanceContext.projectId}]`), instanceContext.dataset && parts.push(`[dataset:${instanceContext.dataset}]`), instanceContext.instanceId && parts.push(`[instance:${instanceContext.instanceId.slice(0, 8)}]`)), parts.push(message), [parts.join(" "), context];
|
|
130
|
-
}
|
|
131
|
-
function sanitizeContext(context) {
|
|
132
|
-
if (!context || Object.keys(context).length === 0) return;
|
|
133
|
-
const sanitized = { ...context }, sensitiveKeys = ["token", "password", "secret", "apiKey", "authorization"];
|
|
134
|
-
for (const key of Object.keys(sanitized))
|
|
135
|
-
sensitiveKeys.some((sensitive) => key.toLowerCase().includes(sensitive)) && (sanitized[key] = "[REDACTED]");
|
|
136
|
-
return sanitized;
|
|
137
|
-
}
|
|
138
|
-
function createLogger(namespace, baseContext) {
|
|
139
|
-
const logAtLevel = (level, message, context) => {
|
|
140
|
-
if (!isNamespaceEnabled(namespace) || !isLevelEnabled(level) || context?.internal && !globalConfig.internal) return;
|
|
141
|
-
const mergedContext = { ...baseContext, ...context }, sanitized = sanitizeContext(mergedContext), [formatted, finalContext] = formatMessage(namespace, level, message, sanitized);
|
|
142
|
-
globalConfig.handler[level](formatted, finalContext);
|
|
143
|
-
};
|
|
144
|
-
return {
|
|
145
|
-
namespace,
|
|
146
|
-
error: (message, context) => logAtLevel("error", message, context),
|
|
147
|
-
warn: (message, context) => logAtLevel("warn", message, context),
|
|
148
|
-
info: (message, context) => logAtLevel("info", message, context),
|
|
149
|
-
debug: (message, context) => logAtLevel("debug", message, context),
|
|
150
|
-
trace: (message, context) => logAtLevel("trace", message, { ...context, internal: !0 }),
|
|
151
|
-
isLevelEnabled: (level) => isNamespaceEnabled(namespace) && isLevelEnabled(level),
|
|
152
|
-
child: (childContext) => createLogger(namespace, { ...baseContext, ...childContext }),
|
|
153
|
-
getInstanceContext: () => baseContext?.instanceContext
|
|
154
|
-
};
|
|
155
|
-
}
|
|
18
|
+
import { CorsOriginError } from "@sanity/client";
|
|
19
|
+
import { CORE_SDK_VERSION } from "./_chunks-es/version.js";
|
|
156
20
|
function createSanityInstance(config = {}) {
|
|
157
21
|
const instanceId = crypto.randomUUID(), disposeListeners = /* @__PURE__ */ new Map(), disposed = { current: !1 }, instanceContext = {
|
|
158
22
|
instanceId,
|
|
@@ -217,7 +81,7 @@ function createSanityInstance(config = {}) {
|
|
|
217
81
|
}), child;
|
|
218
82
|
},
|
|
219
83
|
match: (targetConfig) => {
|
|
220
|
-
if (Object.entries(
|
|
84
|
+
if (Object.entries(pickProperties(targetConfig, ["auth", "projectId", "dataset"])).every(
|
|
221
85
|
([key, value]) => config[key] === value
|
|
222
86
|
))
|
|
223
87
|
return instance;
|
|
@@ -227,870 +91,38 @@ function createSanityInstance(config = {}) {
|
|
|
227
91
|
};
|
|
228
92
|
return instance;
|
|
229
93
|
}
|
|
230
|
-
|
|
231
|
-
if (typeof import.meta < "u" && import.meta.env)
|
|
232
|
-
return import.meta.env[key];
|
|
233
|
-
if (typeof process < "u" && process.env)
|
|
234
|
-
return process.env[key];
|
|
235
|
-
if (typeof window < "u" && window.ENV)
|
|
236
|
-
return window.ENV?.[key];
|
|
237
|
-
}
|
|
238
|
-
function createStoreState(initialState, devToolsOptions) {
|
|
239
|
-
const store = createStore()(devtools(() => initialState, devToolsOptions));
|
|
240
|
-
return {
|
|
241
|
-
get: store.getState,
|
|
242
|
-
set: (actionKey, updatedState) => {
|
|
243
|
-
const currentState = store.getState(), nextState = typeof updatedState == "function" ? updatedState(currentState) : updatedState;
|
|
244
|
-
currentState !== nextState && store.setState(nextState, !1, actionKey);
|
|
245
|
-
},
|
|
246
|
-
observable: new Observable((observer) => {
|
|
247
|
-
const emit = () => observer.next(store.getState());
|
|
248
|
-
emit();
|
|
249
|
-
const unsubscribe = store.subscribe(emit);
|
|
250
|
-
return () => unsubscribe();
|
|
251
|
-
})
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
function createStoreInstance(instance, key, { name, getInitialState: getInitialState2, initialize }) {
|
|
255
|
-
const state = createStoreState(getInitialState2(instance, key), {
|
|
256
|
-
enabled: !!getEnv("DEV"),
|
|
257
|
-
name: `${name}-${key.name}`
|
|
258
|
-
}), dispose = initialize?.({ state, instance, key }), disposed = { current: !1 };
|
|
259
|
-
return {
|
|
260
|
-
state,
|
|
261
|
-
dispose: () => {
|
|
262
|
-
disposed.current || (disposed.current = !0, dispose?.());
|
|
263
|
-
},
|
|
264
|
-
isDisposed: () => disposed.current
|
|
265
|
-
};
|
|
266
|
-
}
|
|
267
|
-
function createActionBinder(keyFn) {
|
|
268
|
-
const instanceRegistry = /* @__PURE__ */ new Map(), storeRegistry = /* @__PURE__ */ new Map();
|
|
269
|
-
return function(storeDefinition, action) {
|
|
270
|
-
return function(instance, ...params) {
|
|
271
|
-
const key = keyFn(instance, ...params), compositeKey = storeDefinition.name + (key.name ? `:${key.name}` : "");
|
|
272
|
-
let instances = instanceRegistry.get(compositeKey);
|
|
273
|
-
instances || (instances = /* @__PURE__ */ new Set(), instanceRegistry.set(compositeKey, instances)), instances.has(instance.instanceId) || (instances.add(instance.instanceId), instance.onDispose(() => {
|
|
274
|
-
instances.delete(instance.instanceId), instances.size === 0 && (storeRegistry.get(compositeKey)?.dispose(), storeRegistry.delete(compositeKey), instanceRegistry.delete(compositeKey));
|
|
275
|
-
}));
|
|
276
|
-
let storeInstance = storeRegistry.get(compositeKey);
|
|
277
|
-
return storeInstance || (storeInstance = createStoreInstance(instance, key, storeDefinition), storeRegistry.set(compositeKey, storeInstance)), action({ instance, state: storeInstance.state, key }, ...params);
|
|
278
|
-
};
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
const bindActionByDataset = createActionBinder((instance, options) => {
|
|
282
|
-
const projectId = options?.projectId ?? instance.config.projectId, dataset = options?.dataset ?? instance.config.dataset;
|
|
283
|
-
if (!projectId || !dataset)
|
|
284
|
-
throw new Error("This API requires a project ID and dataset configured.");
|
|
285
|
-
return { name: `${projectId}.${dataset}`, projectId, dataset };
|
|
286
|
-
}), createSourceKey = (instance, source) => {
|
|
287
|
-
let name, sourceForKey;
|
|
288
|
-
if (source) {
|
|
289
|
-
if (sourceForKey = source, isDatasetSource(source))
|
|
290
|
-
name = `${source.projectId}.${source.dataset}`;
|
|
291
|
-
else if (isMediaLibrarySource(source))
|
|
292
|
-
name = `media-library:${source.mediaLibraryId}`;
|
|
293
|
-
else if (isCanvasSource(source))
|
|
294
|
-
name = `canvas:${source.canvasId}`;
|
|
295
|
-
else
|
|
296
|
-
throw new Error(`Received invalid source: ${JSON.stringify(source)}`);
|
|
297
|
-
return { name, source: sourceForKey };
|
|
298
|
-
}
|
|
299
|
-
const { projectId, dataset } = instance.config;
|
|
300
|
-
if (!projectId || !dataset)
|
|
301
|
-
throw new Error("This API requires a project ID and dataset configured.");
|
|
302
|
-
return { name: `${projectId}.${dataset}`, source: { projectId, dataset } };
|
|
303
|
-
}, bindActionBySource = createActionBinder((instance, { source }) => createSourceKey(instance, source)), bindActionBySourceAndPerspective = createActionBinder((instance, options) => {
|
|
304
|
-
const { source, perspective } = options, utilizedPerspective = perspective ?? instance.config.perspective ?? "drafts";
|
|
305
|
-
let perspectiveKey;
|
|
306
|
-
isReleasePerspective(utilizedPerspective) ? perspectiveKey = utilizedPerspective.releaseName : typeof utilizedPerspective == "string" ? perspectiveKey = utilizedPerspective : perspectiveKey = JSON.stringify(utilizedPerspective);
|
|
307
|
-
const sourceKey = createSourceKey(instance, source);
|
|
308
|
-
return {
|
|
309
|
-
name: `${sourceKey.name}:${perspectiveKey}`,
|
|
310
|
-
source: sourceKey.source,
|
|
311
|
-
perspective: utilizedPerspective
|
|
312
|
-
};
|
|
313
|
-
}), bindActionGlobally = createActionBinder((..._rest) => ({ name: "global" }));
|
|
314
|
-
function createStateSourceAction(options) {
|
|
315
|
-
const selector = typeof options == "function" ? options : options.selector, subscribeHandler = options && "onSubscribe" in options ? options.onSubscribe : void 0, isEqual2 = options && "isEqual" in options ? options.isEqual ?? Object.is : Object.is, selectorContextCache = /* @__PURE__ */ new WeakMap();
|
|
316
|
-
function stateSourceAction(context, ...params) {
|
|
317
|
-
const { state, instance } = context, getCurrent = () => {
|
|
318
|
-
const currentState = state.get();
|
|
319
|
-
if (typeof currentState != "object" || currentState === null)
|
|
320
|
-
throw new Error(
|
|
321
|
-
`Expected store state to be an object but got "${typeof currentState}" instead`
|
|
322
|
-
);
|
|
323
|
-
let instanceCache = selectorContextCache.get(currentState);
|
|
324
|
-
instanceCache || (instanceCache = /* @__PURE__ */ new WeakMap(), selectorContextCache.set(currentState, instanceCache));
|
|
325
|
-
let selectorContext = instanceCache.get(instance);
|
|
326
|
-
return selectorContext || (selectorContext = { state: currentState, instance }, instanceCache.set(instance, selectorContext)), selector(selectorContext, ...params);
|
|
327
|
-
}, subscribe = (onStoreChanged) => {
|
|
328
|
-
const cleanup = subscribeHandler?.(context, ...params), subscription = state.observable.pipe(
|
|
329
|
-
// Derive value from current state
|
|
330
|
-
map(getCurrent),
|
|
331
|
-
// Filter unchanged values using custom equality check
|
|
332
|
-
distinctUntilChanged(isEqual2),
|
|
333
|
-
// Skip initial emission since we only want changes
|
|
334
|
-
skip(1)
|
|
335
|
-
).subscribe({
|
|
336
|
-
next: () => onStoreChanged?.(),
|
|
337
|
-
// Propagate selector errors to both subscription types
|
|
338
|
-
error: () => onStoreChanged?.()
|
|
339
|
-
});
|
|
340
|
-
return () => {
|
|
341
|
-
subscription.unsubscribe(), cleanup?.();
|
|
342
|
-
};
|
|
343
|
-
}, observable = new Observable((observer) => {
|
|
344
|
-
const emitCurrent = () => {
|
|
345
|
-
try {
|
|
346
|
-
observer.next(getCurrent());
|
|
347
|
-
} catch (error) {
|
|
348
|
-
observer.error(error);
|
|
349
|
-
}
|
|
350
|
-
};
|
|
351
|
-
return emitCurrent(), subscribe(emitCurrent);
|
|
352
|
-
}).pipe(share());
|
|
353
|
-
return {
|
|
354
|
-
getCurrent,
|
|
355
|
-
subscribe,
|
|
356
|
-
observable
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
return stateSourceAction;
|
|
360
|
-
}
|
|
361
|
-
const DEFAULT_BASE = "http://localhost", AUTH_CODE_PARAM = "sid", DEFAULT_API_VERSION$1 = "2021-06-07", REQUEST_TAG_PREFIX = "sanity.sdk.auth";
|
|
362
|
-
function resolveAuthMode(config, locationHref) {
|
|
363
|
-
return isStudioConfig(config) ? "studio" : detectDashboardContext(locationHref) ? "dashboard" : "standalone";
|
|
364
|
-
}
|
|
365
|
-
function isStudioConfig(config) {
|
|
366
|
-
return !!config.studio || !!config.studioMode?.enabled;
|
|
367
|
-
}
|
|
368
|
-
function detectDashboardContext(locationHref) {
|
|
369
|
-
try {
|
|
370
|
-
const contextParam = new URL(locationHref, DEFAULT_BASE).searchParams.get("_context");
|
|
371
|
-
if (!contextParam) return !1;
|
|
372
|
-
const parsed = JSON.parse(contextParam);
|
|
373
|
-
return typeof parsed == "object" && parsed !== null && !Array.isArray(parsed) && Object.keys(parsed).length > 0;
|
|
374
|
-
} catch (err) {
|
|
375
|
-
return console.error("Failed to parse dashboard context from initial location:", err), !1;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
var AuthStateType = /* @__PURE__ */ ((AuthStateType2) => (AuthStateType2.LOGGED_IN = "logged-in", AuthStateType2.LOGGING_IN = "logging-in", AuthStateType2.ERROR = "error", AuthStateType2.LOGGED_OUT = "logged-out", AuthStateType2))(AuthStateType || {});
|
|
379
|
-
const REFRESH_INTERVAL = 720 * 60 * 1e3, LOCK_NAME = "sanity-token-refresh-lock";
|
|
380
|
-
function getLastRefreshTime(storageArea, storageKey) {
|
|
381
|
-
try {
|
|
382
|
-
const data = storageArea?.getItem(`${storageKey}_last_refresh`), parsed = data ? parseInt(data, 10) : 0;
|
|
383
|
-
return isNaN(parsed) ? 0 : parsed;
|
|
384
|
-
} catch {
|
|
385
|
-
return 0;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
function setLastRefreshTime(storageArea, storageKey) {
|
|
389
|
-
try {
|
|
390
|
-
storageArea?.setItem(`${storageKey}_last_refresh`, Date.now().toString());
|
|
391
|
-
} catch {
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
function getNextRefreshDelay(storageArea, storageKey) {
|
|
395
|
-
const lastRefresh = getLastRefreshTime(storageArea, storageKey);
|
|
396
|
-
if (!lastRefresh) return 0;
|
|
397
|
-
const now = Date.now(), nextRefreshTime = lastRefresh + REFRESH_INTERVAL;
|
|
398
|
-
return Math.max(0, nextRefreshTime - now);
|
|
399
|
-
}
|
|
400
|
-
function createTokenRefreshStream(token, clientFactory, apiHost) {
|
|
401
|
-
return new Observable((subscriber) => {
|
|
402
|
-
const subscription = clientFactory({
|
|
403
|
-
apiVersion: DEFAULT_API_VERSION$1,
|
|
404
|
-
requestTagPrefix: "token-refresh",
|
|
405
|
-
useProjectHostname: !1,
|
|
406
|
-
useCdn: !1,
|
|
407
|
-
token,
|
|
408
|
-
ignoreBrowserTokenWarning: !0,
|
|
409
|
-
...apiHost && { apiHost }
|
|
410
|
-
}).observable.request({
|
|
411
|
-
uri: "auth/refresh-token",
|
|
412
|
-
method: "POST",
|
|
413
|
-
body: {
|
|
414
|
-
token
|
|
415
|
-
}
|
|
416
|
-
}).subscribe(subscriber);
|
|
417
|
-
return () => subscription.unsubscribe();
|
|
418
|
-
});
|
|
419
|
-
}
|
|
420
|
-
async function acquireTokenRefreshLock(refreshFn, storageArea, storageKey) {
|
|
421
|
-
if (!navigator.locks)
|
|
422
|
-
return console.warn("Web Locks API not supported. Proceeding with uncoordinated refresh."), await refreshFn(), setLastRefreshTime(storageArea, storageKey), !0;
|
|
423
|
-
try {
|
|
424
|
-
return await navigator.locks.request(LOCK_NAME, { mode: "exclusive" }, async (lock) => {
|
|
425
|
-
if (!lock) return !1;
|
|
426
|
-
for (; ; ) {
|
|
427
|
-
const delay2 = getNextRefreshDelay(storageArea, storageKey);
|
|
428
|
-
delay2 > 0 && await new Promise((resolve) => setTimeout(resolve, delay2));
|
|
429
|
-
try {
|
|
430
|
-
await refreshFn(), setLastRefreshTime(storageArea, storageKey);
|
|
431
|
-
} catch (error) {
|
|
432
|
-
console.error("Token refresh failed within lock:", error);
|
|
433
|
-
}
|
|
434
|
-
await new Promise((resolve) => setTimeout(resolve, REFRESH_INTERVAL));
|
|
435
|
-
}
|
|
436
|
-
}) === !0;
|
|
437
|
-
} catch (error) {
|
|
438
|
-
return console.error("Failed to request token refresh lock:", error), !1;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
function shouldRefreshToken(lastRefresh) {
|
|
442
|
-
return lastRefresh ? Date.now() - lastRefresh >= REFRESH_INTERVAL : !0;
|
|
443
|
-
}
|
|
444
|
-
const refreshStampedToken = ({ state }) => {
|
|
445
|
-
const { clientFactory, apiHost, storageArea, storageKey } = state.get().options;
|
|
446
|
-
return state.observable.pipe(
|
|
447
|
-
map((storeState) => ({
|
|
448
|
-
authState: storeState.authState,
|
|
449
|
-
dashboardContext: storeState.dashboardContext
|
|
450
|
-
})),
|
|
451
|
-
filter(
|
|
452
|
-
(storeState) => storeState.authState.type === AuthStateType.LOGGED_IN
|
|
453
|
-
),
|
|
454
|
-
distinctUntilChanged(
|
|
455
|
-
(prev, curr) => prev.authState.type === curr.authState.type && prev.authState.token === curr.authState.token && // Only care about token for distinctness here
|
|
456
|
-
prev.dashboardContext === curr.dashboardContext
|
|
457
|
-
),
|
|
458
|
-
// Make distinctness check explicit
|
|
459
|
-
filter((storeState) => storeState.authState.token.includes("-st")),
|
|
460
|
-
// Ensure we only try to refresh stamped tokens
|
|
461
|
-
exhaustMap((storeState) => {
|
|
462
|
-
const performRefresh = async () => {
|
|
463
|
-
const currentState = state.get();
|
|
464
|
-
if (currentState.authState.type !== AuthStateType.LOGGED_IN)
|
|
465
|
-
throw new Error("User logged out before refresh could complete");
|
|
466
|
-
const currentToken = currentState.authState.token, response = await firstValueFrom(
|
|
467
|
-
createTokenRefreshStream(currentToken, clientFactory, apiHost)
|
|
468
|
-
);
|
|
469
|
-
state.set("setRefreshStampedToken", (prev) => ({
|
|
470
|
-
authState: prev.authState.type === AuthStateType.LOGGED_IN ? { ...prev.authState, token: response.token } : prev.authState
|
|
471
|
-
})), storageArea?.setItem(storageKey, JSON.stringify({ token: response.token }));
|
|
472
|
-
};
|
|
473
|
-
return storeState.dashboardContext ? new Observable((subscriber) => {
|
|
474
|
-
const visibilityHandler = () => {
|
|
475
|
-
const currentState = state.get();
|
|
476
|
-
document.visibilityState === "visible" && currentState.authState.type === AuthStateType.LOGGED_IN && shouldRefreshToken(currentState.authState.lastTokenRefresh) && createTokenRefreshStream(
|
|
477
|
-
currentState.authState.token,
|
|
478
|
-
clientFactory,
|
|
479
|
-
apiHost
|
|
480
|
-
).subscribe({
|
|
481
|
-
next: (response) => {
|
|
482
|
-
state.set("setRefreshStampedToken", (prev) => ({
|
|
483
|
-
authState: prev.authState.type === AuthStateType.LOGGED_IN ? {
|
|
484
|
-
...prev.authState,
|
|
485
|
-
token: response.token,
|
|
486
|
-
lastTokenRefresh: Date.now()
|
|
487
|
-
} : prev.authState
|
|
488
|
-
})), subscriber.next(response);
|
|
489
|
-
},
|
|
490
|
-
error: (error) => subscriber.error(error)
|
|
491
|
-
});
|
|
492
|
-
}, timerSubscription = timer(REFRESH_INTERVAL, REFRESH_INTERVAL).pipe(
|
|
493
|
-
filter(() => document.visibilityState === "visible"),
|
|
494
|
-
switchMap(() => {
|
|
495
|
-
const currentState = state.get().authState;
|
|
496
|
-
if (currentState.type !== AuthStateType.LOGGED_IN)
|
|
497
|
-
throw new Error("User logged out before refresh could complete");
|
|
498
|
-
return createTokenRefreshStream(currentState.token, clientFactory, apiHost);
|
|
499
|
-
})
|
|
500
|
-
).subscribe({
|
|
501
|
-
next: (response) => {
|
|
502
|
-
state.set("setRefreshStampedToken", (prev) => ({
|
|
503
|
-
authState: prev.authState.type === AuthStateType.LOGGED_IN ? {
|
|
504
|
-
...prev.authState,
|
|
505
|
-
token: response.token,
|
|
506
|
-
lastTokenRefresh: Date.now()
|
|
507
|
-
} : prev.authState
|
|
508
|
-
})), subscriber.next(response);
|
|
509
|
-
},
|
|
510
|
-
error: (error) => subscriber.error(error)
|
|
511
|
-
});
|
|
512
|
-
return document.addEventListener("visibilitychange", visibilityHandler), () => {
|
|
513
|
-
document.removeEventListener("visibilitychange", visibilityHandler), timerSubscription.unsubscribe();
|
|
514
|
-
};
|
|
515
|
-
}).pipe(
|
|
516
|
-
takeWhile(() => state.get().authState.type === AuthStateType.LOGGED_IN),
|
|
517
|
-
map((response) => ({ token: response.token }))
|
|
518
|
-
) : from(acquireTokenRefreshLock(performRefresh, storageArea, storageKey)).pipe(
|
|
519
|
-
filter((hasLock) => hasLock),
|
|
520
|
-
map(() => {
|
|
521
|
-
const currentState = state.get().authState;
|
|
522
|
-
if (currentState.type !== AuthStateType.LOGGED_IN)
|
|
523
|
-
throw new Error("User logged out before refresh could complete");
|
|
524
|
-
return { token: currentState.token };
|
|
525
|
-
})
|
|
526
|
-
);
|
|
527
|
-
})
|
|
528
|
-
).subscribe({
|
|
529
|
-
next: (response) => {
|
|
530
|
-
state.set("setRefreshStampedToken", (prev) => ({
|
|
531
|
-
authState: prev.authState.type === AuthStateType.LOGGED_IN ? {
|
|
532
|
-
...prev.authState,
|
|
533
|
-
token: response.token,
|
|
534
|
-
lastTokenRefresh: Date.now()
|
|
535
|
-
} : prev.authState
|
|
536
|
-
})), storageArea?.setItem(storageKey, JSON.stringify({ token: response.token }));
|
|
537
|
-
},
|
|
538
|
-
error: (error) => {
|
|
539
|
-
state.set("setRefreshStampedTokenError", { authState: { type: AuthStateType.ERROR, error } });
|
|
540
|
-
}
|
|
541
|
-
});
|
|
542
|
-
}, subscribeToStateAndFetchCurrentUser = ({ state, instance }, fetchOptions) => {
|
|
543
|
-
const { clientFactory, apiHost } = state.get().options, useProjectHostname = fetchOptions?.useProjectHostname ?? isStudioConfig(instance.config), projectId = instance.config.projectId;
|
|
544
|
-
return state.observable.pipe(
|
|
545
|
-
map(({ authState, options: storeOptions }) => ({
|
|
546
|
-
authState,
|
|
547
|
-
authMethod: storeOptions.authMethod
|
|
548
|
-
})),
|
|
549
|
-
filter(
|
|
550
|
-
(value) => value.authState.type === AuthStateType.LOGGED_IN && !value.authState.currentUser
|
|
551
|
-
),
|
|
552
|
-
map((value) => ({ token: value.authState.token, authMethod: value.authMethod })),
|
|
553
|
-
distinctUntilChanged(
|
|
554
|
-
(prev, curr) => prev.token === curr.token && prev.authMethod === curr.authMethod
|
|
555
|
-
)
|
|
556
|
-
).pipe(
|
|
557
|
-
map(
|
|
558
|
-
({ token, authMethod }) => clientFactory({
|
|
559
|
-
apiVersion: DEFAULT_API_VERSION$1,
|
|
560
|
-
requestTagPrefix: REQUEST_TAG_PREFIX,
|
|
561
|
-
token: authMethod === "cookie" ? void 0 : token,
|
|
562
|
-
ignoreBrowserTokenWarning: !0,
|
|
563
|
-
useProjectHostname,
|
|
564
|
-
useCdn: !1,
|
|
565
|
-
...authMethod === "cookie" ? { withCredentials: !0 } : {},
|
|
566
|
-
...useProjectHostname && projectId ? { projectId } : {},
|
|
567
|
-
...apiHost && { apiHost }
|
|
568
|
-
})
|
|
569
|
-
),
|
|
570
|
-
switchMap(
|
|
571
|
-
(client) => client.observable.request({ uri: "/users/me", method: "GET" })
|
|
572
|
-
)
|
|
573
|
-
).subscribe({
|
|
574
|
-
next: (currentUser) => {
|
|
575
|
-
state.set("setCurrentUser", (prev) => ({
|
|
576
|
-
authState: prev.authState.type === AuthStateType.LOGGED_IN ? { ...prev.authState, currentUser } : prev.authState
|
|
577
|
-
}));
|
|
578
|
-
},
|
|
579
|
-
error: (error) => {
|
|
580
|
-
state.set("setError", { authState: { type: AuthStateType.ERROR, error } });
|
|
581
|
-
}
|
|
582
|
-
});
|
|
583
|
-
};
|
|
584
|
-
function getAuthCode(callbackUrl, locationHref) {
|
|
585
|
-
const loc = new URL(locationHref, DEFAULT_BASE), callbackLocation = callbackUrl ? new URL(callbackUrl, DEFAULT_BASE) : void 0, callbackLocationMatches = callbackLocation ? loc.pathname.toLowerCase().startsWith(callbackLocation.pathname.toLowerCase()) : !0;
|
|
586
|
-
let authCode = new URLSearchParams(loc.hash.slice(1)).get(AUTH_CODE_PARAM) || new URLSearchParams(loc.search).get(AUTH_CODE_PARAM);
|
|
587
|
-
if (!authCode) {
|
|
588
|
-
const contextParam = new URLSearchParams(loc.search).get("_context");
|
|
589
|
-
if (contextParam)
|
|
590
|
-
try {
|
|
591
|
-
const parsedContext = JSON.parse(contextParam);
|
|
592
|
-
parsedContext && typeof parsedContext == "object" && typeof parsedContext.sid == "string" && parsedContext.sid && (authCode = parsedContext.sid);
|
|
593
|
-
} catch {
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
return authCode && callbackLocationMatches ? authCode : null;
|
|
597
|
-
}
|
|
598
|
-
function getTokenFromLocation(locationHref) {
|
|
599
|
-
const loc = new URL(locationHref);
|
|
600
|
-
return new URLSearchParams(loc.hash.slice(1)).get("token") || null;
|
|
601
|
-
}
|
|
602
|
-
function getTokenFromStorage(storageArea, storageKey) {
|
|
603
|
-
if (!storageArea) return null;
|
|
604
|
-
const item = storageArea.getItem(storageKey);
|
|
605
|
-
if (item === null) return null;
|
|
606
|
-
try {
|
|
607
|
-
const parsed = JSON.parse(item);
|
|
608
|
-
if (typeof parsed != "object" || parsed === null || !("token" in parsed) || typeof parsed.token != "string")
|
|
609
|
-
throw new Error("Invalid stored auth data structure");
|
|
610
|
-
return parsed.token;
|
|
611
|
-
} catch {
|
|
612
|
-
return storageArea.removeItem(storageKey), null;
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
function getStorageEvents() {
|
|
616
|
-
return typeof window < "u" && typeof window.addEventListener == "function" ? fromEvent(window, "storage") : EMPTY;
|
|
617
|
-
}
|
|
618
|
-
function getDefaultStorage() {
|
|
619
|
-
try {
|
|
620
|
-
return typeof localStorage < "u" && typeof localStorage.getItem == "function" ? localStorage : void 0;
|
|
621
|
-
} catch {
|
|
622
|
-
return;
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
function getDefaultLocation() {
|
|
626
|
-
try {
|
|
627
|
-
return typeof location > "u" ? DEFAULT_BASE : typeof location.href == "string" ? location.href : DEFAULT_BASE;
|
|
628
|
-
} catch {
|
|
629
|
-
return DEFAULT_BASE;
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
function getCleanedUrl(locationUrl) {
|
|
633
|
-
const loc = new URL(locationUrl), rawHash = loc.hash.startsWith("#") ? loc.hash.slice(1) : loc.hash;
|
|
634
|
-
if (rawHash && rawHash.includes("=")) {
|
|
635
|
-
const hashParams = new URLSearchParams(rawHash);
|
|
636
|
-
hashParams.delete("token"), hashParams.delete("withSid");
|
|
637
|
-
const nextHash = hashParams.toString();
|
|
638
|
-
loc.hash = nextHash ? `#${nextHash}` : "";
|
|
639
|
-
}
|
|
640
|
-
return loc.searchParams.delete("sid"), loc.searchParams.delete("url"), loc.toString();
|
|
641
|
-
}
|
|
642
|
-
function getClientErrorApiBody(error) {
|
|
643
|
-
const body = error.response?.body;
|
|
644
|
-
return body && typeof body == "object" ? body : void 0;
|
|
645
|
-
}
|
|
646
|
-
function getClientErrorApiType(error) {
|
|
647
|
-
const body = getClientErrorApiBody(error);
|
|
648
|
-
return body?.error?.type ?? body?.type;
|
|
649
|
-
}
|
|
650
|
-
function getClientErrorApiDescription(error) {
|
|
651
|
-
const body = getClientErrorApiBody(error);
|
|
652
|
-
return body?.error?.description ?? body?.description;
|
|
653
|
-
}
|
|
654
|
-
function isProjectUserNotFoundClientError(error) {
|
|
655
|
-
return getClientErrorApiType(error) === "projectUserNotFoundError";
|
|
656
|
-
}
|
|
657
|
-
function parseDashboardContext(locationHref) {
|
|
658
|
-
try {
|
|
659
|
-
const contextParam = new URL(locationHref, DEFAULT_BASE).searchParams.get("_context");
|
|
660
|
-
if (contextParam) {
|
|
661
|
-
const parsedContext = JSON.parse(contextParam);
|
|
662
|
-
if (parsedContext && typeof parsedContext == "object" && !Array.isArray(parsedContext) && Object.keys(parsedContext).length > 0)
|
|
663
|
-
return delete parsedContext.sid, parsedContext;
|
|
664
|
-
}
|
|
665
|
-
} catch (err) {
|
|
666
|
-
console.error("Failed to parse dashboard context from initial location:", err);
|
|
667
|
-
}
|
|
668
|
-
return {};
|
|
669
|
-
}
|
|
670
|
-
function getDashboardInitialState(options) {
|
|
671
|
-
const { authConfig, initialLocationHref } = options, providedToken = authConfig.token, callbackUrl = authConfig.callbackUrl, storageKey = "__sanity_auth_token", dashboardContext = parseDashboardContext(initialLocationHref), storageArea = void 0;
|
|
672
|
-
return providedToken ? {
|
|
673
|
-
authState: { type: AuthStateType.LOGGED_IN, token: providedToken, currentUser: null },
|
|
674
|
-
storageKey,
|
|
675
|
-
storageArea,
|
|
676
|
-
authMethod: void 0,
|
|
677
|
-
dashboardContext
|
|
678
|
-
} : getAuthCode(callbackUrl, initialLocationHref) || getTokenFromLocation(initialLocationHref) ? {
|
|
679
|
-
authState: { type: AuthStateType.LOGGING_IN, isExchangingToken: !1 },
|
|
680
|
-
storageKey,
|
|
681
|
-
storageArea,
|
|
682
|
-
authMethod: void 0,
|
|
683
|
-
dashboardContext
|
|
684
|
-
} : {
|
|
685
|
-
authState: { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 },
|
|
686
|
-
storageKey,
|
|
687
|
-
storageArea,
|
|
688
|
-
authMethod: void 0,
|
|
689
|
-
dashboardContext
|
|
690
|
-
};
|
|
691
|
-
}
|
|
692
|
-
function initializeDashboardAuth(context, tokenRefresherRunning2) {
|
|
693
|
-
const subscriptions = [];
|
|
694
|
-
let startedRefresher = !1;
|
|
695
|
-
return subscriptions.push(subscribeToStateAndFetchCurrentUser(context, { useProjectHostname: !1 })), tokenRefresherRunning2 || (startedRefresher = !0, subscriptions.push(refreshStampedToken(context))), {
|
|
696
|
-
dispose: () => {
|
|
697
|
-
for (const subscription of subscriptions)
|
|
698
|
-
subscription.unsubscribe();
|
|
699
|
-
},
|
|
700
|
-
tokenRefresherStarted: startedRefresher
|
|
701
|
-
};
|
|
702
|
-
}
|
|
703
|
-
const subscribeToStorageEventsAndSetToken = ({
|
|
704
|
-
state
|
|
705
|
-
}) => {
|
|
706
|
-
const { storageArea, storageKey } = state.get().options;
|
|
707
|
-
return defer(getStorageEvents).pipe(
|
|
708
|
-
filter(
|
|
709
|
-
(e) => e.storageArea === storageArea && e.key === storageKey
|
|
710
|
-
),
|
|
711
|
-
map(() => getTokenFromStorage(storageArea, storageKey)),
|
|
712
|
-
distinctUntilChanged()
|
|
713
|
-
).subscribe((token) => {
|
|
714
|
-
state.set("updateTokenFromStorageEvent", {
|
|
715
|
-
authState: token ? { type: AuthStateType.LOGGED_IN, token, currentUser: null } : { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 }
|
|
716
|
-
});
|
|
717
|
-
});
|
|
718
|
-
};
|
|
719
|
-
function getStandaloneInitialState(options) {
|
|
720
|
-
const { authConfig, initialLocationHref } = options, providedToken = authConfig.token, callbackUrl = authConfig.callbackUrl, storageKey = "__sanity_auth_token", storageArea = authConfig.storageArea ?? getDefaultStorage();
|
|
721
|
-
if (providedToken)
|
|
722
|
-
return {
|
|
723
|
-
authState: { type: AuthStateType.LOGGED_IN, token: providedToken, currentUser: null },
|
|
724
|
-
storageKey,
|
|
725
|
-
storageArea,
|
|
726
|
-
authMethod: void 0,
|
|
727
|
-
dashboardContext: {}
|
|
728
|
-
};
|
|
729
|
-
if (getAuthCode(callbackUrl, initialLocationHref) || getTokenFromLocation(initialLocationHref))
|
|
730
|
-
return {
|
|
731
|
-
authState: { type: AuthStateType.LOGGING_IN, isExchangingToken: !1 },
|
|
732
|
-
storageKey,
|
|
733
|
-
storageArea,
|
|
734
|
-
authMethod: void 0,
|
|
735
|
-
dashboardContext: {}
|
|
736
|
-
};
|
|
737
|
-
const token = getTokenFromStorage(storageArea, storageKey);
|
|
738
|
-
return token ? {
|
|
739
|
-
authState: { type: AuthStateType.LOGGED_IN, token, currentUser: null },
|
|
740
|
-
storageKey,
|
|
741
|
-
storageArea,
|
|
742
|
-
authMethod: "localstorage",
|
|
743
|
-
dashboardContext: {}
|
|
744
|
-
} : {
|
|
745
|
-
authState: { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 },
|
|
746
|
-
storageKey,
|
|
747
|
-
storageArea,
|
|
748
|
-
authMethod: void 0,
|
|
749
|
-
dashboardContext: {}
|
|
750
|
-
};
|
|
751
|
-
}
|
|
752
|
-
function initializeStandaloneAuth(context, tokenRefresherRunning2) {
|
|
753
|
-
const subscriptions = [];
|
|
754
|
-
let startedRefresher = !1;
|
|
755
|
-
return subscriptions.push(subscribeToStateAndFetchCurrentUser(context, { useProjectHostname: !1 })), context.state.get().options?.storageArea && subscriptions.push(subscribeToStorageEventsAndSetToken(context)), tokenRefresherRunning2 || (startedRefresher = !0, subscriptions.push(refreshStampedToken(context))), {
|
|
756
|
-
dispose: () => {
|
|
757
|
-
for (const subscription of subscriptions)
|
|
758
|
-
subscription.unsubscribe();
|
|
759
|
-
},
|
|
760
|
-
tokenRefresherStarted: startedRefresher
|
|
761
|
-
};
|
|
762
|
-
}
|
|
763
|
-
const COOKIE_AUTH_TIMEOUT_MS = 1e4;
|
|
764
|
-
async function checkForCookieAuth(projectId, clientFactory) {
|
|
765
|
-
if (!projectId) return !1;
|
|
766
|
-
try {
|
|
767
|
-
const user = await clientFactory({
|
|
768
|
-
projectId,
|
|
769
|
-
useCdn: !1,
|
|
770
|
-
requestTagPrefix: "sdk",
|
|
771
|
-
timeout: COOKIE_AUTH_TIMEOUT_MS
|
|
772
|
-
}).request({
|
|
773
|
-
uri: "/users/me",
|
|
774
|
-
withCredentials: !0,
|
|
775
|
-
tag: "users.get-current"
|
|
776
|
-
});
|
|
777
|
-
return user != null && typeof user == "object" && typeof user.id == "string";
|
|
778
|
-
} catch {
|
|
779
|
-
return !1;
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
function getStudioTokenFromLocalStorage(storageArea, storageKey) {
|
|
783
|
-
return !storageArea || !storageKey ? null : getTokenFromStorage(storageArea, storageKey) || null;
|
|
784
|
-
}
|
|
785
|
-
function getStudioInitialState(options) {
|
|
786
|
-
const { authConfig, projectId, tokenSource } = options, storageArea = authConfig.storageArea ?? getDefaultStorage(), studioStorageKey = `__studio_auth_token_${projectId ?? ""}`;
|
|
787
|
-
if (tokenSource)
|
|
788
|
-
return {
|
|
789
|
-
authState: { type: AuthStateType.LOGGING_IN, isExchangingToken: !1 },
|
|
790
|
-
storageKey: studioStorageKey,
|
|
791
|
-
storageArea,
|
|
792
|
-
authMethod: void 0,
|
|
793
|
-
dashboardContext: {}
|
|
794
|
-
};
|
|
795
|
-
const providedToken = authConfig.token;
|
|
796
|
-
let authMethod;
|
|
797
|
-
const token = getStudioTokenFromLocalStorage(storageArea, studioStorageKey);
|
|
798
|
-
return token && (authMethod = "localstorage"), providedToken ? {
|
|
799
|
-
authState: { type: AuthStateType.LOGGED_IN, token: providedToken, currentUser: null },
|
|
800
|
-
storageKey: studioStorageKey,
|
|
801
|
-
storageArea,
|
|
802
|
-
authMethod,
|
|
803
|
-
dashboardContext: {}
|
|
804
|
-
} : token ? {
|
|
805
|
-
authState: { type: AuthStateType.LOGGED_IN, token, currentUser: null },
|
|
806
|
-
storageKey: studioStorageKey,
|
|
807
|
-
storageArea,
|
|
808
|
-
authMethod: "localstorage",
|
|
809
|
-
dashboardContext: {}
|
|
810
|
-
} : {
|
|
811
|
-
authState: { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 },
|
|
812
|
-
storageKey: studioStorageKey,
|
|
813
|
-
storageArea,
|
|
814
|
-
authMethod: void 0,
|
|
815
|
-
dashboardContext: {}
|
|
816
|
-
};
|
|
817
|
-
}
|
|
818
|
-
function initializeStudioAuth(context, tokenRefresherRunning2) {
|
|
819
|
-
const tokenSource = context.instance.config.studio?.auth?.token;
|
|
820
|
-
return tokenSource ? initializeWithTokenSource(context, tokenSource) : initializeWithFallback(context, tokenRefresherRunning2);
|
|
821
|
-
}
|
|
822
|
-
function initializeWithTokenSource(context, tokenSource) {
|
|
823
|
-
const subscriptions = [];
|
|
824
|
-
subscriptions.push(subscribeToStateAndFetchCurrentUser(context, { useProjectHostname: !0 }));
|
|
825
|
-
const tokenSub = tokenSource.subscribe({
|
|
826
|
-
next: (token) => {
|
|
827
|
-
const { state } = context;
|
|
828
|
-
token ? state.set("studioTokenSource", (prev) => ({
|
|
829
|
-
options: { ...prev.options, authMethod: void 0 },
|
|
830
|
-
authState: { type: AuthStateType.LOGGED_IN, token, currentUser: null }
|
|
831
|
-
})) : state.set("studioTokenSourceLoggedOut", (prev) => ({
|
|
832
|
-
options: { ...prev.options, authMethod: void 0 },
|
|
833
|
-
authState: { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 }
|
|
834
|
-
}));
|
|
835
|
-
}
|
|
836
|
-
});
|
|
837
|
-
return {
|
|
838
|
-
dispose: () => {
|
|
839
|
-
tokenSub.unsubscribe();
|
|
840
|
-
for (const subscription of subscriptions)
|
|
841
|
-
subscription.unsubscribe();
|
|
842
|
-
},
|
|
843
|
-
// Studio handles token refresh — do not start the SDK's refresher
|
|
844
|
-
tokenRefresherStarted: !1
|
|
845
|
-
};
|
|
846
|
-
}
|
|
847
|
-
function initializeWithFallback(context, tokenRefresherRunning2) {
|
|
848
|
-
const subscriptions = [];
|
|
849
|
-
let startedRefresher = !1;
|
|
850
|
-
subscriptions.push(subscribeToStateAndFetchCurrentUser(context, { useProjectHostname: !0 })), context.state.get().options?.storageArea && subscriptions.push(subscribeToStorageEventsAndSetToken(context));
|
|
851
|
-
try {
|
|
852
|
-
const { instance, state } = context;
|
|
853
|
-
if (!(state.get().authState?.type === AuthStateType.LOGGED_IN && state.get().authState.token)) {
|
|
854
|
-
const projectIdValue = instance.config.projectId, clientFactory = state.get().options.clientFactory;
|
|
855
|
-
checkForCookieAuth(projectIdValue, clientFactory).then((isCookieAuthEnabled) => {
|
|
856
|
-
isCookieAuthEnabled && state.set("enableCookieAuth", (prev) => ({
|
|
857
|
-
options: { ...prev.options, authMethod: "cookie" },
|
|
858
|
-
authState: prev.authState.type === AuthStateType.LOGGED_IN ? prev.authState : { type: AuthStateType.LOGGED_IN, token: "", currentUser: null }
|
|
859
|
-
}));
|
|
860
|
-
});
|
|
861
|
-
}
|
|
862
|
-
} catch {
|
|
863
|
-
}
|
|
864
|
-
return tokenRefresherRunning2 || (startedRefresher = !0, subscriptions.push(refreshStampedToken(context))), {
|
|
865
|
-
dispose: () => {
|
|
866
|
-
for (const subscription of subscriptions)
|
|
867
|
-
subscription.unsubscribe();
|
|
868
|
-
},
|
|
869
|
-
tokenRefresherStarted: startedRefresher
|
|
870
|
-
};
|
|
871
|
-
}
|
|
872
|
-
let tokenRefresherRunning = !1;
|
|
873
|
-
const authStore = {
|
|
874
|
-
name: "Auth",
|
|
875
|
-
getInitialState(instance) {
|
|
876
|
-
const {
|
|
877
|
-
apiHost,
|
|
878
|
-
callbackUrl,
|
|
879
|
-
providers: customProviders,
|
|
880
|
-
token: providedToken,
|
|
881
|
-
clientFactory = createClient,
|
|
882
|
-
initialLocationHref = getDefaultLocation()
|
|
883
|
-
} = instance.config.auth ?? {}, authConfig = instance.config.auth ?? {};
|
|
884
|
-
let loginDomain = "https://www.sanity.io";
|
|
885
|
-
try {
|
|
886
|
-
apiHost && new URL(apiHost).hostname.endsWith(".sanity.work") && (loginDomain = "https://www.sanity.work");
|
|
887
|
-
} catch {
|
|
888
|
-
}
|
|
889
|
-
const loginUrl = new URL("/login", loginDomain);
|
|
890
|
-
loginUrl.searchParams.set("origin", getCleanedUrl(initialLocationHref)), loginUrl.searchParams.set("type", "stampedToken"), loginUrl.searchParams.set("withSid", "true");
|
|
891
|
-
const mode = resolveAuthMode(instance.config, initialLocationHref), strategyOptions = {
|
|
892
|
-
authConfig,
|
|
893
|
-
projectId: instance.config.projectId,
|
|
894
|
-
initialLocationHref,
|
|
895
|
-
tokenSource: instance.config.studio?.auth?.token
|
|
896
|
-
};
|
|
897
|
-
let result;
|
|
898
|
-
switch (mode) {
|
|
899
|
-
case "studio":
|
|
900
|
-
result = getStudioInitialState(strategyOptions);
|
|
901
|
-
break;
|
|
902
|
-
case "dashboard":
|
|
903
|
-
result = getDashboardInitialState(strategyOptions);
|
|
904
|
-
break;
|
|
905
|
-
case "standalone":
|
|
906
|
-
result = getStandaloneInitialState(strategyOptions);
|
|
907
|
-
break;
|
|
908
|
-
}
|
|
909
|
-
return {
|
|
910
|
-
authState: result.authState,
|
|
911
|
-
dashboardContext: result.dashboardContext,
|
|
912
|
-
options: {
|
|
913
|
-
apiHost,
|
|
914
|
-
loginUrl: loginUrl.toString(),
|
|
915
|
-
callbackUrl,
|
|
916
|
-
customProviders,
|
|
917
|
-
providedToken,
|
|
918
|
-
clientFactory,
|
|
919
|
-
initialLocationHref,
|
|
920
|
-
storageKey: result.storageKey,
|
|
921
|
-
storageArea: result.storageArea,
|
|
922
|
-
authMethod: result.authMethod
|
|
923
|
-
}
|
|
924
|
-
};
|
|
925
|
-
},
|
|
926
|
-
initialize(context) {
|
|
927
|
-
const initialLocationHref = context.state.get().options?.initialLocationHref ?? getDefaultLocation(), mode = resolveAuthMode(context.instance.config, initialLocationHref);
|
|
928
|
-
let initResult;
|
|
929
|
-
switch (mode) {
|
|
930
|
-
case "studio":
|
|
931
|
-
initResult = initializeStudioAuth(context, tokenRefresherRunning);
|
|
932
|
-
break;
|
|
933
|
-
case "dashboard":
|
|
934
|
-
initResult = initializeDashboardAuth(context, tokenRefresherRunning);
|
|
935
|
-
break;
|
|
936
|
-
case "standalone":
|
|
937
|
-
initResult = initializeStandaloneAuth(context, tokenRefresherRunning);
|
|
938
|
-
break;
|
|
939
|
-
}
|
|
940
|
-
return initResult.tokenRefresherStarted && (tokenRefresherRunning = !0), initResult.dispose;
|
|
941
|
-
}
|
|
942
|
-
}, getCurrentUserState = bindActionGlobally(
|
|
943
|
-
authStore,
|
|
944
|
-
createStateSourceAction(
|
|
945
|
-
({ state: { authState } }) => authState.type === AuthStateType.LOGGED_IN ? authState.currentUser : null
|
|
946
|
-
)
|
|
947
|
-
), getTokenState = bindActionGlobally(
|
|
948
|
-
authStore,
|
|
949
|
-
createStateSourceAction(
|
|
950
|
-
({ state: { authState } }) => authState.type === AuthStateType.LOGGED_IN ? authState.token : null
|
|
951
|
-
)
|
|
952
|
-
), getAuthMethodState = bindActionGlobally(
|
|
953
|
-
authStore,
|
|
954
|
-
createStateSourceAction(({ state: { options } }) => options.authMethod)
|
|
955
|
-
), getLoginUrlState = bindActionGlobally(
|
|
956
|
-
authStore,
|
|
957
|
-
createStateSourceAction(({ state: { options } }) => options.loginUrl)
|
|
958
|
-
), getAuthState = bindActionGlobally(
|
|
959
|
-
authStore,
|
|
960
|
-
createStateSourceAction(({ state: { authState } }) => authState)
|
|
961
|
-
), getDashboardOrganizationId$1 = bindActionGlobally(
|
|
962
|
-
authStore,
|
|
963
|
-
createStateSourceAction(({ state: { dashboardContext } }) => dashboardContext?.orgId)
|
|
964
|
-
), getIsInDashboardState = bindActionGlobally(
|
|
965
|
-
authStore,
|
|
966
|
-
createStateSourceAction(
|
|
967
|
-
({ state: { dashboardContext } }) => (
|
|
968
|
-
// Check if dashboardContext exists and is not empty
|
|
969
|
-
!!dashboardContext && Object.keys(dashboardContext).length > 0
|
|
970
|
-
)
|
|
971
|
-
)
|
|
972
|
-
), setAuthToken = bindActionGlobally(authStore, ({ state }, token) => {
|
|
973
|
-
const currentAuthState = state.get().authState;
|
|
974
|
-
token ? (currentAuthState.type !== AuthStateType.LOGGED_IN || currentAuthState.token !== token) && state.set("setToken", {
|
|
975
|
-
authState: {
|
|
976
|
-
type: AuthStateType.LOGGED_IN,
|
|
977
|
-
token,
|
|
978
|
-
// Keep existing user or set to null? Setting to null forces refetch.
|
|
979
|
-
// Keep existing user to avoid unnecessary refetches if user data is still valid.
|
|
980
|
-
currentUser: currentAuthState.type === AuthStateType.LOGGED_IN ? currentAuthState.currentUser : null
|
|
981
|
-
}
|
|
982
|
-
}) : currentAuthState.type !== AuthStateType.LOGGED_OUT && state.set("setToken", {
|
|
983
|
-
authState: { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 }
|
|
984
|
-
});
|
|
985
|
-
}), DEFAULT_API_VERSION = "2024-11-12", DEFAULT_REQUEST_TAG_PREFIX = "sanity.sdk", allowedKeys = Object.keys({
|
|
986
|
-
apiHost: null,
|
|
987
|
-
useCdn: null,
|
|
988
|
-
token: null,
|
|
989
|
-
perspective: null,
|
|
990
|
-
proxy: null,
|
|
991
|
-
withCredentials: null,
|
|
992
|
-
timeout: null,
|
|
993
|
-
maxRetries: null,
|
|
994
|
-
dataset: null,
|
|
995
|
-
projectId: null,
|
|
996
|
-
scope: null,
|
|
997
|
-
apiVersion: null,
|
|
998
|
-
requestTagPrefix: null,
|
|
999
|
-
useProjectHostname: null,
|
|
1000
|
-
"~experimental_resource": null,
|
|
1001
|
-
source: null
|
|
1002
|
-
}), DEFAULT_CLIENT_CONFIG = {
|
|
1003
|
-
apiVersion: DEFAULT_API_VERSION,
|
|
1004
|
-
useCdn: !1,
|
|
1005
|
-
ignoreBrowserTokenWarning: !0,
|
|
1006
|
-
allowReconfigure: !1,
|
|
1007
|
-
requestTagPrefix: DEFAULT_REQUEST_TAG_PREFIX
|
|
1008
|
-
}, clientStore = {
|
|
1009
|
-
name: "clientStore",
|
|
1010
|
-
getInitialState: (instance) => ({
|
|
1011
|
-
clients: {},
|
|
1012
|
-
token: getTokenState(instance).getCurrent()
|
|
1013
|
-
}),
|
|
1014
|
-
initialize(context) {
|
|
1015
|
-
const subscription = listenToToken(context), authMethodSubscription = listenToAuthMethod(context);
|
|
1016
|
-
return () => {
|
|
1017
|
-
subscription.unsubscribe(), authMethodSubscription.unsubscribe();
|
|
1018
|
-
};
|
|
1019
|
-
}
|
|
1020
|
-
}, listenToToken = ({ instance, state }) => getTokenState(instance).observable.subscribe((token) => {
|
|
1021
|
-
state.set("setTokenAndResetClients", { token, clients: {} });
|
|
1022
|
-
}), listenToAuthMethod = ({ instance, state }) => getAuthMethodState(instance).observable.subscribe((authMethod) => {
|
|
1023
|
-
state.set("setAuthMethod", { authMethod });
|
|
1024
|
-
}), getClientConfigKey = (options) => JSON.stringify(pick(options, ...allowedKeys)), getClient = bindActionGlobally(
|
|
1025
|
-
clientStore,
|
|
1026
|
-
({ state, instance }, options) => {
|
|
1027
|
-
if (!options || typeof options != "object")
|
|
1028
|
-
throw new Error(
|
|
1029
|
-
'getClient() requires a configuration object with at least an "apiVersion" property. Example: getClient(instance, { apiVersion: "2024-11-12" })'
|
|
1030
|
-
);
|
|
1031
|
-
const disallowedKeys = Object.keys(options).filter((key2) => !allowedKeys.includes(key2));
|
|
1032
|
-
if (disallowedKeys.length > 0) {
|
|
1033
|
-
const listFormatter = new Intl.ListFormat("en", { style: "long", type: "conjunction" });
|
|
1034
|
-
throw new Error(
|
|
1035
|
-
`The client options provided contains unsupported properties: ${listFormatter.format(disallowedKeys)}. Allowed keys are: ${listFormatter.format(allowedKeys)}.`
|
|
1036
|
-
);
|
|
1037
|
-
}
|
|
1038
|
-
const tokenFromState = state.get().token, { clients, authMethod } = state.get();
|
|
1039
|
-
let resource;
|
|
1040
|
-
options.source && (isDatasetSource(options.source) ? resource = { type: "dataset", id: `${options.source.projectId}.${options.source.dataset}` } : isMediaLibrarySource(options.source) ? resource = { type: "media-library", id: options.source.mediaLibraryId } : isCanvasSource(options.source) && (resource = { type: "canvas", id: options.source.canvasId }));
|
|
1041
|
-
const projectId = options.projectId ?? instance.config.projectId, dataset = options.dataset ?? instance.config.dataset, apiHost = options.apiHost ?? instance.config.auth?.apiHost, effectiveOptions = {
|
|
1042
|
-
...DEFAULT_CLIENT_CONFIG,
|
|
1043
|
-
...(options.scope === "global" || !projectId || resource) && { useProjectHostname: !1 },
|
|
1044
|
-
token: authMethod === "cookie" ? void 0 : tokenFromState ?? void 0,
|
|
1045
|
-
...options,
|
|
1046
|
-
...projectId && { projectId },
|
|
1047
|
-
...dataset && { dataset },
|
|
1048
|
-
...apiHost && { apiHost },
|
|
1049
|
-
...resource && { "~experimental_resource": resource }
|
|
1050
|
-
};
|
|
1051
|
-
resource && ((options.projectId || options.dataset) && console.warn(
|
|
1052
|
-
"Both source and explicit projectId/dataset are provided. The source will be used and projectId/dataset will be ignored."
|
|
1053
|
-
), delete effectiveOptions.projectId, delete effectiveOptions.dataset), effectiveOptions.token === null || typeof effectiveOptions.token > "u" ? (delete effectiveOptions.token, authMethod === "cookie" && (effectiveOptions.withCredentials = !0)) : delete effectiveOptions.withCredentials;
|
|
1054
|
-
const key = getClientConfigKey(effectiveOptions);
|
|
1055
|
-
if (clients[key]) return clients[key];
|
|
1056
|
-
const client = createClient(effectiveOptions);
|
|
1057
|
-
return state.set("addClient", (prev) => ({ clients: { ...prev.clients, [key]: client } })), client;
|
|
1058
|
-
}
|
|
1059
|
-
), getClientState = bindActionGlobally(
|
|
1060
|
-
clientStore,
|
|
1061
|
-
createStateSourceAction(({ instance }, options) => getClient(instance, options))
|
|
1062
|
-
), API_VERSION$6 = "vX";
|
|
94
|
+
const API_VERSION$5 = "vX";
|
|
1063
95
|
function agentGenerate(instance, options) {
|
|
1064
96
|
return getClientState(instance, {
|
|
1065
|
-
apiVersion: API_VERSION$
|
|
97
|
+
apiVersion: API_VERSION$5,
|
|
1066
98
|
projectId: instance.config.projectId,
|
|
1067
99
|
dataset: instance.config.dataset
|
|
1068
100
|
}).observable.pipe(switchMap((client) => client.observable.agent.action.generate(options)));
|
|
1069
101
|
}
|
|
1070
102
|
function agentTransform(instance, options) {
|
|
1071
103
|
return getClientState(instance, {
|
|
1072
|
-
apiVersion: API_VERSION$
|
|
104
|
+
apiVersion: API_VERSION$5,
|
|
1073
105
|
projectId: instance.config.projectId,
|
|
1074
106
|
dataset: instance.config.dataset
|
|
1075
107
|
}).observable.pipe(switchMap((client) => client.observable.agent.action.transform(options)));
|
|
1076
108
|
}
|
|
1077
109
|
function agentTranslate(instance, options) {
|
|
1078
110
|
return getClientState(instance, {
|
|
1079
|
-
apiVersion: API_VERSION$
|
|
111
|
+
apiVersion: API_VERSION$5,
|
|
1080
112
|
projectId: instance.config.projectId,
|
|
1081
113
|
dataset: instance.config.dataset
|
|
1082
114
|
}).observable.pipe(switchMap((client) => client.observable.agent.action.translate(options)));
|
|
1083
115
|
}
|
|
1084
116
|
function agentPrompt(instance, options) {
|
|
1085
117
|
return getClientState(instance, {
|
|
1086
|
-
apiVersion: API_VERSION$
|
|
118
|
+
apiVersion: API_VERSION$5,
|
|
1087
119
|
projectId: instance.config.projectId,
|
|
1088
120
|
dataset: instance.config.dataset
|
|
1089
121
|
}).observable.pipe(switchMap((client) => from(client.agent.action.prompt(options))));
|
|
1090
122
|
}
|
|
1091
123
|
function agentPatch(instance, options) {
|
|
1092
124
|
return getClientState(instance, {
|
|
1093
|
-
apiVersion: API_VERSION$
|
|
125
|
+
apiVersion: API_VERSION$5,
|
|
1094
126
|
projectId: instance.config.projectId,
|
|
1095
127
|
dataset: instance.config.dataset
|
|
1096
128
|
}).observable.pipe(switchMap((client) => from(client.agent.action.patch(options))));
|
|
@@ -1107,7 +139,7 @@ function createFetcherStore({
|
|
|
1107
139
|
fetchThrottleInternal = 1e3,
|
|
1108
140
|
stateExpirationDelay = 5e3
|
|
1109
141
|
}) {
|
|
1110
|
-
const store = {
|
|
142
|
+
const store = defineStore({
|
|
1111
143
|
name,
|
|
1112
144
|
getInitialState: () => ({
|
|
1113
145
|
stateByParams: {}
|
|
@@ -1116,7 +148,7 @@ function createFetcherStore({
|
|
|
1116
148
|
const subscription = subscribeToSubscriptionsAndFetch(context);
|
|
1117
149
|
return () => subscription.unsubscribe();
|
|
1118
150
|
}
|
|
1119
|
-
}, subscribeToSubscriptionsAndFetch = ({
|
|
151
|
+
}), subscribeToSubscriptionsAndFetch = ({
|
|
1120
152
|
state
|
|
1121
153
|
}) => state.observable.pipe(
|
|
1122
154
|
// Map the state to an array of [serialized, entry] pairs.
|
|
@@ -1132,13 +164,13 @@ function createFetcherStore({
|
|
|
1132
164
|
startWith([group$.key, void 0]),
|
|
1133
165
|
pairwise(),
|
|
1134
166
|
// Trigger only when the subscriptions array grows.
|
|
1135
|
-
filter
|
|
167
|
+
filter(([[, prevEntry], [, currEntry]]) => {
|
|
1136
168
|
const prevSubs = prevEntry?.subscriptions ?? [];
|
|
1137
169
|
return (currEntry?.subscriptions ?? []).length > prevSubs.length;
|
|
1138
170
|
}),
|
|
1139
|
-
map
|
|
171
|
+
map(([, [, currEntry]]) => currEntry),
|
|
1140
172
|
// Only trigger if we haven't fetched recently.
|
|
1141
|
-
filter
|
|
173
|
+
filter((entry) => {
|
|
1142
174
|
const lastFetch = entry?.lastFetchInitiatedAt;
|
|
1143
175
|
return lastFetch ? Date.now() - new Date(lastFetch).getTime() >= fetchThrottleInternal : !0;
|
|
1144
176
|
}),
|
|
@@ -1160,8 +192,8 @@ function createFetcherStore({
|
|
|
1160
192
|
stateByParams: {
|
|
1161
193
|
...prev.stateByParams,
|
|
1162
194
|
[entry.key]: {
|
|
1163
|
-
...
|
|
1164
|
-
...
|
|
195
|
+
...omitProperty(entry, "error"),
|
|
196
|
+
...prev.stateByParams[entry.key] ? omitProperty(prev.stateByParams[entry.key], "error") : {},
|
|
1165
197
|
data
|
|
1166
198
|
}
|
|
1167
199
|
}
|
|
@@ -1208,12 +240,12 @@ function createFetcherStore({
|
|
|
1208
240
|
}
|
|
1209
241
|
}
|
|
1210
242
|
})), () => {
|
|
1211
|
-
|
|
243
|
+
setCleanupTimeout(() => {
|
|
1212
244
|
state.set("removeSubscription", (prev) => {
|
|
1213
245
|
const entry = prev.stateByParams[key];
|
|
1214
246
|
if (!entry) return prev;
|
|
1215
247
|
const newSubs = (entry.subscriptions || []).filter((id) => id !== subscriptionId);
|
|
1216
|
-
return newSubs.length === 0 ? { stateByParams:
|
|
248
|
+
return newSubs.length === 0 ? { stateByParams: omitProperty(prev.stateByParams, key) } : {
|
|
1217
249
|
stateByParams: {
|
|
1218
250
|
...prev.stateByParams,
|
|
1219
251
|
[key]: {
|
|
@@ -1233,7 +265,7 @@ function createFetcherStore({
|
|
|
1233
265
|
);
|
|
1234
266
|
return { getState, resolveState };
|
|
1235
267
|
}
|
|
1236
|
-
const API_VERSION$
|
|
268
|
+
const API_VERSION$4 = "v2025-02-19", project = createFetcherStore({
|
|
1237
269
|
name: "Project",
|
|
1238
270
|
getKey: (instance, options) => {
|
|
1239
271
|
const projectId = options?.projectId ?? instance.config.projectId;
|
|
@@ -1244,7 +276,7 @@ const API_VERSION$5 = "v2025-02-19", project = createFetcherStore({
|
|
|
1244
276
|
fetcher: (instance) => (options = {}) => {
|
|
1245
277
|
const projectId = options.projectId ?? instance.config.projectId;
|
|
1246
278
|
return getClientState(instance, {
|
|
1247
|
-
apiVersion: API_VERSION$
|
|
279
|
+
apiVersion: API_VERSION$4,
|
|
1248
280
|
scope: "global",
|
|
1249
281
|
projectId
|
|
1250
282
|
}).observable.pipe(
|
|
@@ -1263,7 +295,7 @@ const API_VERSION$5 = "v2025-02-19", project = createFetcherStore({
|
|
|
1263
295
|
function observeOrganizationVerificationState(instance, projectIds) {
|
|
1264
296
|
const dashboardOrgId$ = getDashboardOrganizationId(instance).observable.pipe(distinctUntilChanged()), projectOrgIdObservables = projectIds.map(
|
|
1265
297
|
(id) => getProjectState(instance, { projectId: id }).observable.pipe(
|
|
1266
|
-
map((project2) => ({ projectId: id, orgId: project2?.organizationId ?? null })),
|
|
298
|
+
map$1((project2) => ({ projectId: id, orgId: project2?.organizationId ?? null })),
|
|
1267
299
|
// Ensure we only proceed if the orgId is loaded, distinct prevents unnecessary checks
|
|
1268
300
|
distinctUntilChanged((prev, curr) => prev.orgId === curr.orgId)
|
|
1269
301
|
)
|
|
@@ -1299,7 +331,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1299
331
|
const cleanedUrl = getCleanedUrl(locationHref), tokenFromUrl = getTokenFromLocation(locationHref);
|
|
1300
332
|
if (tokenFromUrl)
|
|
1301
333
|
return state.set("setTokenFromUrl", {
|
|
1302
|
-
authState:
|
|
334
|
+
authState: createLoggedInAuthState(tokenFromUrl, null)
|
|
1303
335
|
}), cleanedUrl;
|
|
1304
336
|
const authCode = getAuthCode(callbackUrl, locationHref);
|
|
1305
337
|
if (!authCode) return !1;
|
|
@@ -1320,7 +352,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1320
352
|
});
|
|
1321
353
|
try {
|
|
1322
354
|
const client = clientFactory({
|
|
1323
|
-
apiVersion: DEFAULT_API_VERSION
|
|
355
|
+
apiVersion: DEFAULT_API_VERSION,
|
|
1324
356
|
requestTagPrefix: REQUEST_TAG_PREFIX,
|
|
1325
357
|
useProjectHostname: !1,
|
|
1326
358
|
useCdn: !1,
|
|
@@ -1331,7 +363,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1331
363
|
query: { sid: authCode },
|
|
1332
364
|
tag: "fetch-token"
|
|
1333
365
|
});
|
|
1334
|
-
return storageArea?.setItem(storageKey, JSON.stringify({ token })), state.set("setToken", { authState:
|
|
366
|
+
return storageArea?.setItem(storageKey, JSON.stringify({ token })), state.set("setToken", { authState: createLoggedInAuthState(token, null) }), cleanedUrl;
|
|
1335
367
|
} catch (error) {
|
|
1336
368
|
return state.set("exchangeSessionForTokenError", { authState: { type: AuthStateType.ERROR, error } }), cleanedUrl;
|
|
1337
369
|
}
|
|
@@ -1348,11 +380,11 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1348
380
|
}), await clientFactory({
|
|
1349
381
|
token,
|
|
1350
382
|
requestTagPrefix: REQUEST_TAG_PREFIX,
|
|
1351
|
-
apiVersion: DEFAULT_API_VERSION
|
|
383
|
+
apiVersion: DEFAULT_API_VERSION,
|
|
1352
384
|
...apiHost && { apiHost },
|
|
1353
385
|
useProjectHostname: !1,
|
|
1354
386
|
useCdn: !1
|
|
1355
|
-
}).request({ uri: "/auth/logout", method: "POST" }));
|
|
387
|
+
}).request({ uri: "/auth/logout", method: "POST", tag: "logout" }));
|
|
1356
388
|
} finally {
|
|
1357
389
|
state.set("logoutSuccess", {
|
|
1358
390
|
authState: { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 }
|
|
@@ -1370,7 +402,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1370
402
|
throw new Error("Controller must be initialized before using or creating channels");
|
|
1371
403
|
const channels = state.get().channels, existing = channels.get(options.name);
|
|
1372
404
|
if (existing) {
|
|
1373
|
-
if (!
|
|
405
|
+
if (!isDeepEqual(existing.options, options))
|
|
1374
406
|
throw new Error(`Channel "${options.name}" already exists with different options`);
|
|
1375
407
|
return state.set("incrementChannelRefCount", {
|
|
1376
408
|
channels: new Map(channels).set(options.name, {
|
|
@@ -1408,7 +440,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1408
440
|
})
|
|
1409
441
|
});
|
|
1410
442
|
}
|
|
1411
|
-
}, comlinkControllerStore = {
|
|
443
|
+
}, comlinkControllerStore = defineStore({
|
|
1412
444
|
name: "connectionStore",
|
|
1413
445
|
getInitialState: () => ({
|
|
1414
446
|
controller: null,
|
|
@@ -1420,7 +452,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1420
452
|
destroyController(instance);
|
|
1421
453
|
};
|
|
1422
454
|
}
|
|
1423
|
-
}, destroyController = bindActionGlobally(
|
|
455
|
+
}), destroyController = bindActionGlobally(
|
|
1424
456
|
comlinkControllerStore,
|
|
1425
457
|
destroyController$1
|
|
1426
458
|
), getOrCreateChannel = bindActionGlobally(
|
|
@@ -1432,7 +464,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1432
464
|
), releaseChannel = bindActionGlobally(comlinkControllerStore, releaseChannel$1), getOrCreateNode$1 = ({ state }, options) => {
|
|
1433
465
|
const nodes = state.get().nodes, existing = nodes.get(options.name);
|
|
1434
466
|
if (existing) {
|
|
1435
|
-
if (!
|
|
467
|
+
if (!isDeepEqual(existing.options, options))
|
|
1436
468
|
throw new Error(`Node "${options.name}" already exists with different options`);
|
|
1437
469
|
return existing.node.start(), existing.node;
|
|
1438
470
|
}
|
|
@@ -1461,7 +493,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1461
493
|
existing.statusUnsub && existing.statusUnsub(), existing.node.stop(), nodes.delete(name), state.set("removeNode", { nodes });
|
|
1462
494
|
return;
|
|
1463
495
|
}
|
|
1464
|
-
}, comlinkNodeStore = {
|
|
496
|
+
}, comlinkNodeStore = defineStore({
|
|
1465
497
|
name: "nodeStore",
|
|
1466
498
|
getInitialState: () => ({
|
|
1467
499
|
nodes: /* @__PURE__ */ new Map(),
|
|
@@ -1474,7 +506,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1474
506
|
});
|
|
1475
507
|
};
|
|
1476
508
|
}
|
|
1477
|
-
}, releaseNode = bindActionGlobally(comlinkNodeStore, releaseNode$1), getOrCreateNode = bindActionGlobally(comlinkNodeStore, getOrCreateNode$1), NODE_RELEASE_TIME = 5e3, selectNode = (context, nodeInput) => context.state.nodes.get(nodeInput.name), getNodeState = bindActionGlobally(
|
|
509
|
+
}), releaseNode = bindActionGlobally(comlinkNodeStore, releaseNode$1), getOrCreateNode = bindActionGlobally(comlinkNodeStore, getOrCreateNode$1), NODE_RELEASE_TIME = 5e3, selectNode = (context, nodeInput) => context.state.nodes.get(nodeInput.name), getNodeState = bindActionGlobally(
|
|
1478
510
|
comlinkNodeStore,
|
|
1479
511
|
createStateSourceAction({
|
|
1480
512
|
selector: createSelector([selectNode], (nodeEntry) => nodeEntry?.status === "connected" ? {
|
|
@@ -1486,7 +518,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1486
518
|
getOrCreateNode(instance, nodeInput);
|
|
1487
519
|
let subs = state.get().subscriptions.get(nodeName);
|
|
1488
520
|
return subs || (subs = /* @__PURE__ */ new Set(), state.get().subscriptions.set(nodeName, subs)), subs.add(subscriberId), () => {
|
|
1489
|
-
|
|
521
|
+
setCleanupTimeout(() => {
|
|
1490
522
|
const activeSubs = state.get().subscriptions.get(nodeName);
|
|
1491
523
|
activeSubs && (activeSubs.delete(subscriberId), activeSubs.size === 0 && (state.get().subscriptions.delete(nodeName), releaseNode(instance, nodeName)));
|
|
1492
524
|
}, NODE_RELEASE_TIME);
|
|
@@ -1521,7 +553,7 @@ function configureLogging(config) {
|
|
|
1521
553
|
source: "programmatic"
|
|
1522
554
|
});
|
|
1523
555
|
}
|
|
1524
|
-
const API_VERSION$
|
|
556
|
+
const API_VERSION$3 = "v2025-02-19", datasets = createFetcherStore({
|
|
1525
557
|
name: "Datasets",
|
|
1526
558
|
getKey: (instance, options) => {
|
|
1527
559
|
const projectId = options?.projectId ?? instance.config.projectId;
|
|
@@ -1530,27 +562,31 @@ const API_VERSION$4 = "v2025-02-19", datasets = createFetcherStore({
|
|
|
1530
562
|
return projectId;
|
|
1531
563
|
},
|
|
1532
564
|
fetcher: (instance) => (options) => getClientState(instance, {
|
|
1533
|
-
apiVersion: API_VERSION$
|
|
565
|
+
apiVersion: API_VERSION$3,
|
|
1534
566
|
// non-null assertion is fine because we check above
|
|
1535
567
|
projectId: options?.projectId ?? instance.config.projectId,
|
|
1536
568
|
useProjectHostname: !0
|
|
1537
569
|
}).observable.pipe(switchMap((client) => client.observable.datasets.list()))
|
|
1538
|
-
}), getDatasetsState = datasets.getState, resolveDatasets = datasets.resolveState
|
|
570
|
+
}), getDatasetsState = datasets.getState, resolveDatasets = datasets.resolveState;
|
|
571
|
+
function getEffectiveDocumentId(doc) {
|
|
572
|
+
return doc.liveEdit ? doc.documentId : isReleasePerspective(doc.perspective) ? getVersionId(DocumentId(doc.documentId), doc.perspective.releaseName) : getPublishedId(DocumentId(doc.documentId));
|
|
573
|
+
}
|
|
574
|
+
const isSanityMutatePatch = (value) => !(typeof value != "object" || !value || !("type" in value) || typeof value.type != "string" || value.type !== "patch" || !("id" in value) || typeof value.id != "string" || !("patches" in value) || !Array.isArray(value.patches));
|
|
1539
575
|
function createDocument(doc, initialValue) {
|
|
1540
|
-
|
|
576
|
+
let effectiveDocumentId;
|
|
577
|
+
return typeof doc.documentId == "string" && (effectiveDocumentId = getEffectiveDocumentId({ ...doc, documentId: doc.documentId })), {
|
|
1541
578
|
type: "document.create",
|
|
1542
579
|
...doc,
|
|
1543
|
-
...
|
|
1544
|
-
documentId: doc.liveEdit ? doc.documentId : getPublishedId(doc.documentId)
|
|
1545
|
-
},
|
|
580
|
+
...effectiveDocumentId && { documentId: effectiveDocumentId },
|
|
1546
581
|
...initialValue && { initialValue }
|
|
1547
582
|
};
|
|
1548
583
|
}
|
|
1549
584
|
function deleteDocument(doc) {
|
|
585
|
+
const effectiveDocumentId = getEffectiveDocumentId(doc);
|
|
1550
586
|
return {
|
|
1551
587
|
type: "document.delete",
|
|
1552
588
|
...doc,
|
|
1553
|
-
documentId:
|
|
589
|
+
documentId: effectiveDocumentId
|
|
1554
590
|
};
|
|
1555
591
|
}
|
|
1556
592
|
function convertSanityMutatePatch(sanityPatchMutation) {
|
|
@@ -1560,45 +596,48 @@ function convertSanityMutatePatch(sanityPatchMutation) {
|
|
|
1560
596
|
});
|
|
1561
597
|
}
|
|
1562
598
|
function editDocument(doc, patches) {
|
|
1563
|
-
const
|
|
599
|
+
const effectiveDocumentId = getEffectiveDocumentId(doc);
|
|
1564
600
|
if (isSanityMutatePatch(patches)) {
|
|
1565
601
|
const converted = convertSanityMutatePatch(patches) ?? [];
|
|
1566
602
|
return {
|
|
1567
603
|
...doc,
|
|
1568
604
|
type: "document.edit",
|
|
1569
|
-
documentId,
|
|
605
|
+
documentId: effectiveDocumentId,
|
|
1570
606
|
patches: converted
|
|
1571
607
|
};
|
|
1572
608
|
}
|
|
1573
609
|
return {
|
|
1574
610
|
...doc,
|
|
1575
611
|
type: "document.edit",
|
|
1576
|
-
documentId,
|
|
612
|
+
documentId: effectiveDocumentId,
|
|
1577
613
|
...patches && { patches: Array.isArray(patches) ? patches : [patches] }
|
|
1578
614
|
};
|
|
1579
615
|
}
|
|
1580
616
|
function publishDocument(doc) {
|
|
617
|
+
const effectiveDocumentId = getEffectiveDocumentId(doc);
|
|
1581
618
|
return {
|
|
1582
619
|
type: "document.publish",
|
|
1583
620
|
...doc,
|
|
1584
|
-
documentId:
|
|
621
|
+
documentId: effectiveDocumentId
|
|
1585
622
|
};
|
|
1586
623
|
}
|
|
1587
624
|
function unpublishDocument(doc) {
|
|
625
|
+
const effectiveDocumentId = getEffectiveDocumentId(doc);
|
|
1588
626
|
return {
|
|
1589
627
|
type: "document.unpublish",
|
|
1590
628
|
...doc,
|
|
1591
|
-
documentId:
|
|
629
|
+
documentId: effectiveDocumentId
|
|
1592
630
|
};
|
|
1593
631
|
}
|
|
1594
632
|
function discardDocument(doc) {
|
|
633
|
+
const effectiveDocumentId = getEffectiveDocumentId(doc);
|
|
1595
634
|
return {
|
|
1596
635
|
type: "document.discard",
|
|
1597
636
|
...doc,
|
|
1598
|
-
documentId:
|
|
637
|
+
documentId: effectiveDocumentId
|
|
1599
638
|
};
|
|
1600
639
|
}
|
|
1601
|
-
const DOCUMENT_STATE_CLEAR_DELAY = 1e3, INITIAL_OUTGOING_THROTTLE_TIME = 1e3, API_VERSION$
|
|
640
|
+
const DOCUMENT_STATE_CLEAR_DELAY = 1e3, INITIAL_OUTGOING_THROTTLE_TIME = 1e3, API_VERSION$2 = "v2025-05-06";
|
|
1602
641
|
function generateArrayKey(length = 12) {
|
|
1603
642
|
const numBytes = Math.ceil(length / 2), bytes = crypto.getRandomValues(new Uint8Array(numBytes));
|
|
1604
643
|
return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("").slice(0, length);
|
|
@@ -1826,7 +865,7 @@ function processMutations({
|
|
|
1826
865
|
throw new Error(
|
|
1827
866
|
`Cannot create document with \`_id\` \`${id}\` because another document with the same ID already exists.`
|
|
1828
867
|
);
|
|
1829
|
-
const
|
|
868
|
+
const document = {
|
|
1830
869
|
// > `_createdAt` and `_updatedAt` may be submitted and will override
|
|
1831
870
|
// > the default which is of course the current time. This can be used
|
|
1832
871
|
// > to reconstruct a data-set with its timestamp structure intact.
|
|
@@ -1839,11 +878,11 @@ function processMutations({
|
|
|
1839
878
|
_rev: transactionId,
|
|
1840
879
|
_id: id
|
|
1841
880
|
};
|
|
1842
|
-
dataset[id] =
|
|
881
|
+
dataset[id] = document;
|
|
1843
882
|
continue;
|
|
1844
883
|
}
|
|
1845
884
|
if ("createOrReplace" in mutation) {
|
|
1846
|
-
const id = getId(mutation.createOrReplace._id), prev = dataset[id],
|
|
885
|
+
const id = getId(mutation.createOrReplace._id), prev = dataset[id], document = {
|
|
1847
886
|
...mutation.createOrReplace,
|
|
1848
887
|
// otherwise, if the mutation provided, a `_createdAt` time, use it,
|
|
1849
888
|
// otherwise default to now
|
|
@@ -1870,13 +909,13 @@ function processMutations({
|
|
|
1870
909
|
_rev: transactionId,
|
|
1871
910
|
_id: id
|
|
1872
911
|
};
|
|
1873
|
-
dataset[id] =
|
|
912
|
+
dataset[id] = document;
|
|
1874
913
|
continue;
|
|
1875
914
|
}
|
|
1876
915
|
if ("createIfNotExists" in mutation) {
|
|
1877
916
|
const id = getId(mutation.createIfNotExists._id);
|
|
1878
917
|
if (dataset[id]) continue;
|
|
1879
|
-
const
|
|
918
|
+
const document = {
|
|
1880
919
|
// same logic as `create`:
|
|
1881
920
|
// prefer the user's `_createdAt` and `_updatedAt`
|
|
1882
921
|
_createdAt: now,
|
|
@@ -1885,7 +924,7 @@ function processMutations({
|
|
|
1885
924
|
_rev: transactionId,
|
|
1886
925
|
_id: id
|
|
1887
926
|
};
|
|
1888
|
-
dataset[id] =
|
|
927
|
+
dataset[id] = document;
|
|
1889
928
|
continue;
|
|
1890
929
|
}
|
|
1891
930
|
if ("delete" in mutation) {
|
|
@@ -2002,17 +1041,17 @@ const listen = ({ state }, documentId) => {
|
|
|
2002
1041
|
const { sharedListener, fetchDocument } = state.get();
|
|
2003
1042
|
return sharedListener.events.pipe(
|
|
2004
1043
|
concatMap((e) => e.type === "welcome" ? fetchDocument(documentId).pipe(
|
|
2005
|
-
map((
|
|
1044
|
+
map$1((document) => ({ type: "sync", document }))
|
|
2006
1045
|
) : e.type === "mutation" && e.documentId === documentId ? of(e) : EMPTY),
|
|
2007
1046
|
sortListenerEvents(),
|
|
2008
1047
|
withLatestFrom(
|
|
2009
1048
|
state.observable.pipe(
|
|
2010
|
-
map((s) => s.documentStates[documentId]),
|
|
2011
|
-
filter(Boolean),
|
|
1049
|
+
map$1((s) => s.documentStates[documentId]),
|
|
1050
|
+
filter$1(Boolean),
|
|
2012
1051
|
distinctUntilChanged()
|
|
2013
1052
|
)
|
|
2014
1053
|
),
|
|
2015
|
-
map(([next, documentState]) => {
|
|
1054
|
+
map$1(([next, documentState]) => {
|
|
2016
1055
|
if (next.type === "sync")
|
|
2017
1056
|
return {
|
|
2018
1057
|
type: "sync",
|
|
@@ -2021,7 +1060,7 @@ const listen = ({ state }, documentId) => {
|
|
|
2021
1060
|
revision: next.document?._rev,
|
|
2022
1061
|
timestamp: next.document?._updatedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
2023
1062
|
};
|
|
2024
|
-
const [
|
|
1063
|
+
const [document] = Object.values(
|
|
2025
1064
|
processMutations({
|
|
2026
1065
|
documents: { [documentId]: documentState.remote },
|
|
2027
1066
|
mutations: next.mutations,
|
|
@@ -2032,7 +1071,7 @@ const listen = ({ state }, documentId) => {
|
|
|
2032
1071
|
return {
|
|
2033
1072
|
type: "mutation",
|
|
2034
1073
|
documentId,
|
|
2035
|
-
document:
|
|
1074
|
+
document: document ?? null,
|
|
2036
1075
|
revision: transactionId,
|
|
2037
1076
|
timestamp,
|
|
2038
1077
|
...previousRev && { previousRev }
|
|
@@ -2128,7 +1167,15 @@ const documentsCache = new MultiKeyWeakMap(), actionsCache = /* @__PURE__ */ new
|
|
|
2128
1167
|
],
|
|
2129
1168
|
(documentStates, actions) => {
|
|
2130
1169
|
const documentIds = new Set(
|
|
2131
|
-
actions.map((action) =>
|
|
1170
|
+
actions.map((action) => {
|
|
1171
|
+
if (typeof action.documentId != "string") return [];
|
|
1172
|
+
if (action.liveEdit) return [action.documentId];
|
|
1173
|
+
const ids = [
|
|
1174
|
+
getPublishedId(DocumentId(action.documentId)),
|
|
1175
|
+
getDraftId(DocumentId(action.documentId))
|
|
1176
|
+
];
|
|
1177
|
+
return isReleasePerspective(action.perspective) && ids.push(getVersionId(DocumentId(action.documentId), action.perspective.releaseName)), ids;
|
|
1178
|
+
}).flat()
|
|
2132
1179
|
), documents = {};
|
|
2133
1180
|
for (const documentId of documentIds) {
|
|
2134
1181
|
const local = documentStates[documentId]?.local;
|
|
@@ -2155,8 +1202,8 @@ const documentsCache = new MultiKeyWeakMap(), actionsCache = /* @__PURE__ */ new
|
|
|
2155
1202
|
return nestedCache.get(actionsKey) || (nestedCache.set(actionsKey, normalizedActions), normalizedActions);
|
|
2156
1203
|
}
|
|
2157
1204
|
);
|
|
2158
|
-
function checkGrant$1(grantExpr,
|
|
2159
|
-
const value = evaluateSync(grantExpr, { params: { document
|
|
1205
|
+
function checkGrant$1(grantExpr, document) {
|
|
1206
|
+
const value = evaluateSync(grantExpr, { params: { document } });
|
|
2160
1207
|
return value.type === "boolean" && value.data;
|
|
2161
1208
|
}
|
|
2162
1209
|
const enNarrowConjunction = new Intl.ListFormat("en", { style: "narrow", type: "conjunction" });
|
|
@@ -2199,11 +1246,16 @@ const _calculatePermissions = createSelector(
|
|
|
2199
1246
|
}
|
|
2200
1247
|
for (const action of actions)
|
|
2201
1248
|
if (action.type === "document.edit" && !action.patches?.length) {
|
|
2202
|
-
const docId = action.documentId
|
|
2203
|
-
|
|
1249
|
+
const docId = action.documentId;
|
|
1250
|
+
let doc;
|
|
1251
|
+
action.liveEdit ? doc = documents[docId] : isReleasePerspective(action.perspective) ? doc = documents[getVersionId(DocumentId(docId), action.perspective.releaseName)] : doc = documents[getDraftId(DocumentId(docId))] ?? documents[getPublishedId(DocumentId(docId))], doc ? checkGrant$1(grants.update, doc) || reasons.push({
|
|
2204
1252
|
type: "access",
|
|
2205
1253
|
message: `You are not allowed to edit the document with ID "${docId}".`,
|
|
2206
1254
|
documentId: docId
|
|
1255
|
+
}) : isReleasePerspective(action.perspective) ? reasons.push({
|
|
1256
|
+
type: "precondition",
|
|
1257
|
+
message: `The version document with ID "${docId}" could not be found. Please create it or add it to the release first.`,
|
|
1258
|
+
documentId: docId
|
|
2207
1259
|
}) : reasons.push({
|
|
2208
1260
|
type: "precondition",
|
|
2209
1261
|
message: `The document with ID "${docId}" could not be found. Please check that it exists before editing.`,
|
|
@@ -2220,8 +1272,8 @@ const _calculatePermissions = createSelector(
|
|
|
2220
1272
|
};
|
|
2221
1273
|
}
|
|
2222
1274
|
);
|
|
2223
|
-
function checkGrant(grantExpr,
|
|
2224
|
-
const value = evaluateSync(grantExpr, { params: { document
|
|
1275
|
+
function checkGrant(grantExpr, document) {
|
|
1276
|
+
const value = evaluateSync(grantExpr, { params: { document } });
|
|
2225
1277
|
return value.type === "boolean" && value.data;
|
|
2226
1278
|
}
|
|
2227
1279
|
class ActionError extends Error {
|
|
@@ -2254,7 +1306,11 @@ function processActions({
|
|
|
2254
1306
|
transactionId,
|
|
2255
1307
|
message: "This document already exists."
|
|
2256
1308
|
});
|
|
2257
|
-
const newDocBase2 = { _type: action.documentType, _id: documentId
|
|
1309
|
+
const newDocBase2 = { _type: action.documentType, _id: documentId, ...action.initialValue }, mutations2 = [{ create: {
|
|
1310
|
+
_type: action.documentType,
|
|
1311
|
+
_id: documentId,
|
|
1312
|
+
...action.initialValue
|
|
1313
|
+
} }];
|
|
2258
1314
|
if (base = processMutations({
|
|
2259
1315
|
documents: base,
|
|
2260
1316
|
transactionId,
|
|
@@ -2271,29 +1327,27 @@ function processActions({
|
|
|
2271
1327
|
transactionId,
|
|
2272
1328
|
message: `You do not have permission to create document "${documentId}".`
|
|
2273
1329
|
});
|
|
2274
|
-
outgoingMutations.push(...mutations2)
|
|
2275
|
-
actionType: "sanity.action.document.create",
|
|
2276
|
-
publishedId: documentId,
|
|
2277
|
-
attributes: newDocWorking2
|
|
2278
|
-
});
|
|
1330
|
+
outgoingMutations.push(...mutations2);
|
|
2279
1331
|
continue;
|
|
2280
1332
|
}
|
|
2281
|
-
const draftId = getDraftId(documentId), publishedId = getPublishedId(documentId);
|
|
2282
|
-
if (working[draftId])
|
|
1333
|
+
const versionId = isReleasePerspective(action.perspective) ? getVersionId(DocumentId(documentId), action.perspective.releaseName) : void 0, draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId));
|
|
1334
|
+
if (versionId ? working[versionId] : working[draftId]) {
|
|
1335
|
+
const errorDocType = versionId ? "release version" : "draft";
|
|
2283
1336
|
throw new ActionError({
|
|
2284
1337
|
documentId,
|
|
2285
1338
|
transactionId,
|
|
2286
|
-
message:
|
|
1339
|
+
message: `A ${errorDocType} of this document already exists. Please use or discard the existing ${errorDocType} before creating a new one.`
|
|
2287
1340
|
});
|
|
1341
|
+
}
|
|
2288
1342
|
const newDocBase = {
|
|
2289
|
-
...base[publishedId],
|
|
1343
|
+
...base[draftId] ?? base[publishedId],
|
|
2290
1344
|
_type: action.documentType,
|
|
2291
|
-
_id: draftId,
|
|
1345
|
+
_id: versionId ?? draftId,
|
|
2292
1346
|
...action.initialValue
|
|
2293
1347
|
}, newDocWorking = {
|
|
2294
|
-
...working[publishedId],
|
|
1348
|
+
...working[draftId] ?? working[publishedId],
|
|
2295
1349
|
_type: action.documentType,
|
|
2296
|
-
_id: draftId,
|
|
1350
|
+
_id: versionId ?? draftId,
|
|
2297
1351
|
...action.initialValue
|
|
2298
1352
|
}, mutations = [{ create: newDocWorking }];
|
|
2299
1353
|
if (base = processMutations({
|
|
@@ -2306,7 +1360,13 @@ function processActions({
|
|
|
2306
1360
|
transactionId,
|
|
2307
1361
|
mutations,
|
|
2308
1362
|
timestamp
|
|
2309
|
-
}), !checkGrant(grants.create, working[
|
|
1363
|
+
}), versionId && !checkGrant(grants.create, working[versionId]))
|
|
1364
|
+
throw new PermissionActionError({
|
|
1365
|
+
documentId,
|
|
1366
|
+
transactionId,
|
|
1367
|
+
message: `You do not have permission to create a release version for document "${documentId}".`
|
|
1368
|
+
});
|
|
1369
|
+
if (!versionId && !checkGrant(grants.create, working[draftId]))
|
|
2310
1370
|
throw new PermissionActionError({
|
|
2311
1371
|
documentId,
|
|
2312
1372
|
transactionId,
|
|
@@ -2321,6 +1381,12 @@ function processActions({
|
|
|
2321
1381
|
}
|
|
2322
1382
|
case "document.delete": {
|
|
2323
1383
|
const documentId = action.documentId;
|
|
1384
|
+
if (isReleasePerspective(action.perspective))
|
|
1385
|
+
throw new ActionError({
|
|
1386
|
+
documentId,
|
|
1387
|
+
transactionId,
|
|
1388
|
+
message: 'Cannot delete a version document. You may want to use the "unpublish" or "discard" actions instead.'
|
|
1389
|
+
});
|
|
2324
1390
|
if (action.liveEdit) {
|
|
2325
1391
|
if (!working[documentId])
|
|
2326
1392
|
throw new ActionError({
|
|
@@ -2335,13 +1401,10 @@ function processActions({
|
|
|
2335
1401
|
message: "You do not have permission to delete this document."
|
|
2336
1402
|
});
|
|
2337
1403
|
const mutations2 = [{ delete: { id: documentId } }];
|
|
2338
|
-
base = processMutations({ documents: base, transactionId, mutations: mutations2, timestamp }), working = processMutations({ documents: working, transactionId, mutations: mutations2, timestamp }), outgoingMutations.push(...mutations2)
|
|
2339
|
-
actionType: "sanity.action.document.delete",
|
|
2340
|
-
publishedId: documentId
|
|
2341
|
-
});
|
|
1404
|
+
base = processMutations({ documents: base, transactionId, mutations: mutations2, timestamp }), working = processMutations({ documents: working, transactionId, mutations: mutations2, timestamp }), outgoingMutations.push(...mutations2);
|
|
2342
1405
|
continue;
|
|
2343
1406
|
}
|
|
2344
|
-
const draftId = getDraftId(documentId), publishedId = getPublishedId(documentId);
|
|
1407
|
+
const draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId));
|
|
2345
1408
|
if (!working[publishedId])
|
|
2346
1409
|
throw new ActionError({
|
|
2347
1410
|
documentId,
|
|
@@ -2371,14 +1434,14 @@ function processActions({
|
|
|
2371
1434
|
transactionId,
|
|
2372
1435
|
message: `Cannot discard changes for liveEdit document "${documentId}". LiveEdit documents do not support drafts.`
|
|
2373
1436
|
});
|
|
2374
|
-
const
|
|
2375
|
-
if (!working[
|
|
1437
|
+
const versionId = isReleasePerspective(action.perspective) ? getVersionId(DocumentId(documentId), action.perspective.releaseName) : getDraftId(DocumentId(documentId)), mutations = [{ delete: { id: versionId } }];
|
|
1438
|
+
if (!working[versionId])
|
|
2376
1439
|
throw new ActionError({
|
|
2377
1440
|
documentId,
|
|
2378
1441
|
transactionId,
|
|
2379
|
-
message: `There is no draft available to discard for document "${documentId}".`
|
|
1442
|
+
message: `There is no draft or version available to discard for document "${documentId}".`
|
|
2380
1443
|
});
|
|
2381
|
-
if (!checkGrant(grants.update, working[
|
|
1444
|
+
if (!checkGrant(grants.update, working[versionId]))
|
|
2382
1445
|
throw new PermissionActionError({
|
|
2383
1446
|
documentId,
|
|
2384
1447
|
transactionId,
|
|
@@ -2386,7 +1449,7 @@ function processActions({
|
|
|
2386
1449
|
});
|
|
2387
1450
|
base = processMutations({ documents: base, transactionId, mutations, timestamp }), working = processMutations({ documents: working, transactionId, mutations, timestamp }), outgoingMutations.push(...mutations), outgoingActions.push({
|
|
2388
1451
|
actionType: "sanity.action.document.version.discard",
|
|
2389
|
-
versionId
|
|
1452
|
+
versionId
|
|
2390
1453
|
});
|
|
2391
1454
|
continue;
|
|
2392
1455
|
}
|
|
@@ -2421,38 +1484,37 @@ function processActions({
|
|
|
2421
1484
|
transactionId,
|
|
2422
1485
|
mutations: workingMutations2,
|
|
2423
1486
|
timestamp
|
|
2424
|
-
}), outgoingMutations.push(...workingMutations2)
|
|
2425
|
-
...patches2.map(
|
|
2426
|
-
(patch) => ({
|
|
2427
|
-
actionType: "sanity.action.document.edit",
|
|
2428
|
-
// Server requires draftId to have drafts. prefix for validation, even for liveEdit
|
|
2429
|
-
draftId: getDraftId(documentId),
|
|
2430
|
-
publishedId: documentId,
|
|
2431
|
-
patch
|
|
2432
|
-
})
|
|
2433
|
-
)
|
|
2434
|
-
);
|
|
1487
|
+
}), outgoingMutations.push(...workingMutations2);
|
|
2435
1488
|
continue;
|
|
2436
1489
|
}
|
|
2437
|
-
const draftId = getDraftId(documentId), publishedId = getPublishedId(documentId), userPatches = action.patches?.map((patch) => ({
|
|
1490
|
+
const versionId = isReleasePerspective(action.perspective) ? getVersionId(DocumentId(documentId), action.perspective.releaseName) : void 0, draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId)), patchDocumentId = isReleasePerspective(action.perspective) ? versionId : draftId, userPatches = action.patches?.map((patch) => ({
|
|
1491
|
+
patch: { id: patchDocumentId, ...patch }
|
|
1492
|
+
}));
|
|
2438
1493
|
if (!userPatches?.length) continue;
|
|
2439
|
-
if (
|
|
1494
|
+
if (isReleasePerspective(action.perspective)) {
|
|
1495
|
+
if (!working[versionId] && !base[versionId])
|
|
1496
|
+
throw new ActionError({
|
|
1497
|
+
documentId,
|
|
1498
|
+
transactionId,
|
|
1499
|
+
message: "This document does not exist in the release. Please create it or add it to the release first."
|
|
1500
|
+
});
|
|
1501
|
+
} else if (!working[draftId] && !working[publishedId] || !base[draftId] && !base[publishedId])
|
|
2440
1502
|
throw new ActionError({
|
|
2441
1503
|
documentId,
|
|
2442
1504
|
transactionId,
|
|
2443
1505
|
message: "Cannot edit document because it does not exist in draft or published form."
|
|
2444
1506
|
});
|
|
2445
1507
|
const baseMutations = [];
|
|
2446
|
-
!base[draftId] && base[publishedId] && baseMutations.push({ create: { ...base[publishedId], _id: draftId } });
|
|
2447
|
-
const baseBefore = base[
|
|
1508
|
+
!isReleasePerspective(action.perspective) && !base[draftId] && base[publishedId] && baseMutations.push({ create: { ...base[publishedId], _id: draftId } });
|
|
1509
|
+
const baseBefore = base[patchDocumentId] ?? base[publishedId];
|
|
2448
1510
|
userPatches && baseMutations.push(...userPatches), base = processMutations({
|
|
2449
1511
|
documents: base,
|
|
2450
1512
|
transactionId,
|
|
2451
1513
|
mutations: baseMutations,
|
|
2452
1514
|
timestamp
|
|
2453
1515
|
});
|
|
2454
|
-
const baseAfter = base[
|
|
2455
|
-
if (!working[draftId] && working[publishedId]) {
|
|
1516
|
+
const baseAfter = base[patchDocumentId], patches = diffValue(baseBefore, baseAfter), workingMutations = [];
|
|
1517
|
+
if (!isReleasePerspective(action.perspective) && !working[draftId] && working[publishedId]) {
|
|
2456
1518
|
const newDraftFromPublished = { ...working[publishedId], _id: draftId };
|
|
2457
1519
|
if (!checkGrant(grants.create, newDraftFromPublished))
|
|
2458
1520
|
throw new PermissionActionError({
|
|
@@ -2462,46 +1524,44 @@ function processActions({
|
|
|
2462
1524
|
});
|
|
2463
1525
|
workingMutations.push({ create: newDraftFromPublished });
|
|
2464
1526
|
}
|
|
2465
|
-
const workingBefore = working[
|
|
1527
|
+
const workingBefore = working[patchDocumentId] ?? working[publishedId];
|
|
2466
1528
|
if (!checkGrant(grants.update, workingBefore))
|
|
2467
1529
|
throw new PermissionActionError({
|
|
2468
1530
|
documentId,
|
|
2469
1531
|
transactionId,
|
|
2470
1532
|
message: `You do not have permission to edit document "${documentId}".`
|
|
2471
1533
|
});
|
|
2472
|
-
workingMutations.push(...patches.map((patch) => ({ patch: { id:
|
|
1534
|
+
workingMutations.push(...patches.map((patch) => ({ patch: { id: patchDocumentId, ...patch } }))), working = processMutations({
|
|
2473
1535
|
documents: working,
|
|
2474
1536
|
transactionId,
|
|
2475
1537
|
mutations: workingMutations,
|
|
2476
1538
|
timestamp
|
|
2477
1539
|
}), outgoingMutations.push(...workingMutations), outgoingActions.push(
|
|
2478
|
-
...patches.map(
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
})
|
|
2485
|
-
)
|
|
1540
|
+
...patches.map((patch) => ({
|
|
1541
|
+
actionType: "sanity.action.document.edit",
|
|
1542
|
+
draftId: patchDocumentId,
|
|
1543
|
+
publishedId,
|
|
1544
|
+
patch
|
|
1545
|
+
}))
|
|
2486
1546
|
);
|
|
2487
1547
|
continue;
|
|
2488
1548
|
}
|
|
2489
1549
|
case "document.publish": {
|
|
2490
1550
|
const documentId = getId(action.documentId);
|
|
2491
|
-
if (action.liveEdit)
|
|
1551
|
+
if (action.liveEdit || isReleasePerspective(action.perspective))
|
|
2492
1552
|
throw new ActionError({
|
|
2493
1553
|
documentId,
|
|
2494
1554
|
transactionId,
|
|
2495
|
-
message:
|
|
1555
|
+
message: "Cannot publish this document. Publishing is not supported for liveEdit or version (release) documents."
|
|
2496
1556
|
});
|
|
2497
|
-
const draftId = getDraftId(documentId), publishedId = getPublishedId(documentId), workingDraft = working[draftId], baseDraft = base[draftId];
|
|
1557
|
+
const draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId)), workingDraft = working[draftId], baseDraft = base[draftId];
|
|
2498
1558
|
if (!workingDraft || !baseDraft)
|
|
2499
1559
|
throw new ActionError({
|
|
2500
1560
|
documentId,
|
|
2501
1561
|
transactionId,
|
|
2502
1562
|
message: `Cannot publish because no draft version was found for document "${documentId}".`
|
|
2503
1563
|
});
|
|
2504
|
-
if (!
|
|
1564
|
+
if (!isDeepEqual(workingDraft, baseDraft))
|
|
2505
1565
|
throw new ActionError({
|
|
2506
1566
|
documentId,
|
|
2507
1567
|
transactionId,
|
|
@@ -2538,13 +1598,13 @@ function processActions({
|
|
|
2538
1598
|
}
|
|
2539
1599
|
case "document.unpublish": {
|
|
2540
1600
|
const documentId = getId(action.documentId);
|
|
2541
|
-
if (action.liveEdit)
|
|
1601
|
+
if (action.liveEdit || isReleasePerspective(action.perspective))
|
|
2542
1602
|
throw new ActionError({
|
|
2543
1603
|
documentId,
|
|
2544
1604
|
transactionId,
|
|
2545
|
-
message:
|
|
1605
|
+
message: "Cannot unpublish this document. Unpublishing is not supported for liveEdit or version (release) documents."
|
|
2546
1606
|
});
|
|
2547
|
-
const draftId = getDraftId(documentId), publishedId = getPublishedId(documentId);
|
|
1607
|
+
const draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId));
|
|
2548
1608
|
if (!working[publishedId] && !base[publishedId])
|
|
2549
1609
|
throw new ActionError({
|
|
2550
1610
|
documentId,
|
|
@@ -2618,7 +1678,7 @@ const EMPTY_REVISIONS = {};
|
|
|
2618
1678
|
function queueTransaction(prev, transaction) {
|
|
2619
1679
|
const { transactionId, actions } = transaction;
|
|
2620
1680
|
return {
|
|
2621
|
-
...
|
|
1681
|
+
...getDocumentIdsFromHandleLikes(actions).reduce(
|
|
2622
1682
|
(acc, id) => addSubscriptionIdToDocument(acc, id, transactionId),
|
|
2623
1683
|
prev
|
|
2624
1684
|
),
|
|
@@ -2628,7 +1688,7 @@ function queueTransaction(prev, transaction) {
|
|
|
2628
1688
|
function removeQueuedTransaction(prev, transactionId) {
|
|
2629
1689
|
const transaction = prev.queued.find((t) => t.transactionId === transactionId);
|
|
2630
1690
|
return transaction ? {
|
|
2631
|
-
...
|
|
1691
|
+
...getDocumentIdsFromHandleLikes(transaction.actions).reduce(
|
|
2632
1692
|
(acc, id) => removeSubscriptionIdFromDocument(acc, id, transactionId),
|
|
2633
1693
|
prev
|
|
2634
1694
|
),
|
|
@@ -2638,7 +1698,7 @@ function removeQueuedTransaction(prev, transactionId) {
|
|
|
2638
1698
|
function applyFirstQueuedTransaction(prev) {
|
|
2639
1699
|
const queued = prev.queued.at(0);
|
|
2640
1700
|
if (!queued || !prev.grants) return prev;
|
|
2641
|
-
const ids =
|
|
1701
|
+
const ids = getDocumentIdsFromHandleLikes(queued.actions);
|
|
2642
1702
|
if (ids.some((id) => prev.documentStates[id]?.local === void 0)) return prev;
|
|
2643
1703
|
const working = ids.reduce((acc, id) => (acc[id] = prev.documentStates[id]?.local, acc), {}), timestamp = (/* @__PURE__ */ new Date()).toISOString(), result = processActions({
|
|
2644
1704
|
...queued,
|
|
@@ -2690,7 +1750,7 @@ function batchAppliedTransactions([curr, ...rest]) {
|
|
|
2690
1750
|
if (!rest.length) return editAction;
|
|
2691
1751
|
const next = batchAppliedTransactions(rest);
|
|
2692
1752
|
if (next)
|
|
2693
|
-
return next.disableBatching ? editAction : {
|
|
1753
|
+
return next.disableBatching || !!action.liveEdit != !!next.actions[0]?.liveEdit ? editAction : {
|
|
2694
1754
|
disableBatching: !1,
|
|
2695
1755
|
// Use the transactionId from the later (next) transaction.
|
|
2696
1756
|
transactionId: next.transactionId,
|
|
@@ -2748,7 +1808,7 @@ function cleanupOutgoingTransaction(prev) {
|
|
|
2748
1808
|
const { outgoing } = prev;
|
|
2749
1809
|
if (!outgoing) return prev;
|
|
2750
1810
|
let next = prev;
|
|
2751
|
-
const ids =
|
|
1811
|
+
const ids = getDocumentIdsFromHandleLikes(outgoing.actions);
|
|
2752
1812
|
for (const transactionId of outgoing.batchedTransactionIds)
|
|
2753
1813
|
for (const documentId of ids)
|
|
2754
1814
|
next = removeSubscriptionIdFromDocument(next, documentId, transactionId);
|
|
@@ -2780,20 +1840,20 @@ function revertOutgoingTransaction(prev) {
|
|
|
2780
1840
|
const next = {
|
|
2781
1841
|
...documentState,
|
|
2782
1842
|
local: documentId in working ? working[documentId] : local,
|
|
2783
|
-
unverifiedRevisions: prev.outgoing && prev.outgoing.transactionId in unverifiedRevisions ?
|
|
1843
|
+
unverifiedRevisions: prev.outgoing && prev.outgoing.transactionId in unverifiedRevisions ? omitProperty(unverifiedRevisions, prev.outgoing.transactionId) : unverifiedRevisions
|
|
2784
1844
|
};
|
|
2785
1845
|
return [documentId, next];
|
|
2786
1846
|
})
|
|
2787
1847
|
)
|
|
2788
1848
|
};
|
|
2789
1849
|
}
|
|
2790
|
-
function applyRemoteDocument(prev, { document
|
|
1850
|
+
function applyRemoteDocument(prev, { document, documentId, previousRev, revision, timestamp, type }, events) {
|
|
2791
1851
|
if (!prev.grants) return prev;
|
|
2792
1852
|
const prevDocState = prev.documentStates[documentId];
|
|
2793
1853
|
if (!prevDocState) return prev;
|
|
2794
1854
|
const prevUnverifiedRevisions = prevDocState.unverifiedRevisions, revisionToVerify = revision ? prevUnverifiedRevisions?.[revision] : void 0;
|
|
2795
1855
|
let unverifiedRevisions = prevUnverifiedRevisions ?? EMPTY_REVISIONS;
|
|
2796
|
-
if (revision && revisionToVerify && (unverifiedRevisions =
|
|
1856
|
+
if (revision && revisionToVerify && (unverifiedRevisions = omitProperty(prevUnverifiedRevisions, revision)), type === "sync" && (unverifiedRevisions = Object.fromEntries(
|
|
2797
1857
|
Object.entries(unverifiedRevisions).filter(([, unverifiedRevision]) => unverifiedRevision ? new Date(timestamp).getTime() <= new Date(unverifiedRevision.timestamp).getTime() : !1)
|
|
2798
1858
|
)), revisionToVerify && revisionToVerify.previousRev === previousRev)
|
|
2799
1859
|
return {
|
|
@@ -2802,13 +1862,13 @@ function applyRemoteDocument(prev, { document: document2, documentId, previousRe
|
|
|
2802
1862
|
...prev.documentStates,
|
|
2803
1863
|
[documentId]: {
|
|
2804
1864
|
...prevDocState,
|
|
2805
|
-
remote:
|
|
1865
|
+
remote: document,
|
|
2806
1866
|
remoteRev: revision,
|
|
2807
1867
|
unverifiedRevisions
|
|
2808
1868
|
}
|
|
2809
1869
|
}
|
|
2810
1870
|
};
|
|
2811
|
-
let working = { ...prev.applied.at(0)?.previous, [documentId]:
|
|
1871
|
+
let working = { ...prev.applied.at(0)?.previous, [documentId]: document };
|
|
2812
1872
|
const nextApplied = [];
|
|
2813
1873
|
for (const curr of prev.applied)
|
|
2814
1874
|
try {
|
|
@@ -2834,7 +1894,7 @@ function applyRemoteDocument(prev, { document: document2, documentId, previousRe
|
|
|
2834
1894
|
...prev.documentStates,
|
|
2835
1895
|
[documentId]: {
|
|
2836
1896
|
...prevDocState,
|
|
2837
|
-
remote:
|
|
1897
|
+
remote: document,
|
|
2838
1898
|
remoteRev: revision,
|
|
2839
1899
|
local: working[documentId],
|
|
2840
1900
|
unverifiedRevisions
|
|
@@ -2864,17 +1924,10 @@ function removeSubscriptionIdFromDocument(prev, documentId, subscriptionId) {
|
|
|
2864
1924
|
...prev.documentStates,
|
|
2865
1925
|
[documentId]: { ...prevDocState, subscriptions }
|
|
2866
1926
|
}
|
|
2867
|
-
} : { ...prev, documentStates:
|
|
1927
|
+
} : { ...prev, documentStates: omitProperty(prev.documentStates, documentId) } : prev;
|
|
2868
1928
|
}
|
|
2869
|
-
function manageSubscriberIds({ state },
|
|
2870
|
-
const
|
|
2871
|
-
new Set(
|
|
2872
|
-
expandDraftPublished ? (Array.isArray(documentId) ? documentId : [documentId]).flatMap((id) => [
|
|
2873
|
-
getPublishedId$1(id),
|
|
2874
|
-
getDraftId(id)
|
|
2875
|
-
]) : Array.isArray(documentId) ? documentId : [documentId]
|
|
2876
|
-
)
|
|
2877
|
-
), subscriptionId = insecureRandomId();
|
|
1929
|
+
function manageSubscriberIds({ state }, handles) {
|
|
1930
|
+
const documentIds = getDocumentIdsFromHandleLikes(handles), subscriptionId = insecureRandomId();
|
|
2878
1931
|
return state.set(
|
|
2879
1932
|
"addSubscribers",
|
|
2880
1933
|
(prev) => documentIds.reduce(
|
|
@@ -2882,7 +1935,7 @@ function manageSubscriberIds({ state }, documentId, options) {
|
|
|
2882
1935
|
prev
|
|
2883
1936
|
)
|
|
2884
1937
|
), () => {
|
|
2885
|
-
|
|
1938
|
+
setCleanupTimeout(() => {
|
|
2886
1939
|
state.set(
|
|
2887
1940
|
"removeSubscribers",
|
|
2888
1941
|
(prev) => documentIds.reduce(
|
|
@@ -2893,12 +1946,13 @@ function manageSubscriberIds({ state }, documentId, options) {
|
|
|
2893
1946
|
}, DOCUMENT_STATE_CLEAR_DELAY);
|
|
2894
1947
|
};
|
|
2895
1948
|
}
|
|
2896
|
-
function
|
|
2897
|
-
return
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
1949
|
+
function getDocumentIdsFromHandleLikes(handles) {
|
|
1950
|
+
return handles.flatMap((handle) => {
|
|
1951
|
+
const idsForDocument = [];
|
|
1952
|
+
return handle.documentId ? handle.liveEdit ? [handle.documentId] : (isReleasePerspective(handle.perspective) && idsForDocument.push(
|
|
1953
|
+
getVersionId(DocumentId(handle.documentId), handle.perspective.releaseName)
|
|
1954
|
+
), idsForDocument.push(getPublishedId(DocumentId(handle.documentId))), idsForDocument.push(getDraftId(DocumentId(handle.documentId))), idsForDocument) : [];
|
|
1955
|
+
});
|
|
2902
1956
|
}
|
|
2903
1957
|
function getDocumentEvents(outgoing) {
|
|
2904
1958
|
const documentIdsByAction = Object.entries(
|
|
@@ -2923,10 +1977,12 @@ function getDocumentEvents(outgoing) {
|
|
|
2923
1977
|
)
|
|
2924
1978
|
);
|
|
2925
1979
|
}
|
|
2926
|
-
const API_VERSION$
|
|
2927
|
-
function createSharedListener(instance) {
|
|
1980
|
+
const API_VERSION$1 = "v2025-05-06";
|
|
1981
|
+
function createSharedListener(instance, resource) {
|
|
2928
1982
|
const dispose$ = new Subject(), events$ = getClientState(instance, {
|
|
2929
|
-
apiVersion: API_VERSION$
|
|
1983
|
+
apiVersion: API_VERSION$1,
|
|
1984
|
+
// TODO: remove in v3 when we're ready for everything to be queried via resource
|
|
1985
|
+
resource: resource && !isDatasetResource(resource) ? resource : void 0
|
|
2930
1986
|
}).observable.pipe(
|
|
2931
1987
|
switchMap(
|
|
2932
1988
|
(client) => (
|
|
@@ -2960,11 +2016,15 @@ function createSharedListener(instance) {
|
|
|
2960
2016
|
dispose: () => dispose$.next()
|
|
2961
2017
|
};
|
|
2962
2018
|
}
|
|
2963
|
-
function createFetchDocument(instance) {
|
|
2019
|
+
function createFetchDocument(instance, resource) {
|
|
2964
2020
|
return function(documentId) {
|
|
2965
|
-
return getClientState(instance, {
|
|
2021
|
+
return getClientState(instance, {
|
|
2022
|
+
apiVersion: API_VERSION$1,
|
|
2023
|
+
// TODO: remove in v3 when we're ready for everything to be queried via resource
|
|
2024
|
+
resource: resource && !isDatasetResource(resource) ? resource : void 0
|
|
2025
|
+
}).observable.pipe(
|
|
2966
2026
|
switchMap((client) => createDocumentLoaderFromClient(client)(documentId)),
|
|
2967
|
-
map((result) => {
|
|
2027
|
+
map$1((result) => {
|
|
2968
2028
|
if (!result.accessible) {
|
|
2969
2029
|
if (result.reason === "existence") return null;
|
|
2970
2030
|
throw new Error(`Document with ID \`${documentId}\` is inaccessible due to permissions.`);
|
|
@@ -2975,15 +2035,15 @@ function createFetchDocument(instance) {
|
|
|
2975
2035
|
);
|
|
2976
2036
|
};
|
|
2977
2037
|
}
|
|
2978
|
-
const documentStore = {
|
|
2038
|
+
const documentStore = defineStore({
|
|
2979
2039
|
name: "Document",
|
|
2980
|
-
getInitialState: (instance) => ({
|
|
2040
|
+
getInitialState: (instance, { resource }) => ({
|
|
2981
2041
|
documentStates: {},
|
|
2982
2042
|
// these can be emptied on refetch
|
|
2983
2043
|
queued: [],
|
|
2984
2044
|
applied: [],
|
|
2985
|
-
sharedListener: createSharedListener(instance),
|
|
2986
|
-
fetchDocument: createFetchDocument(instance),
|
|
2045
|
+
sharedListener: createSharedListener(instance, resource),
|
|
2046
|
+
fetchDocument: createFetchDocument(instance, resource),
|
|
2987
2047
|
events: new Subject()
|
|
2988
2048
|
}),
|
|
2989
2049
|
initialize(context) {
|
|
@@ -2997,83 +2057,92 @@ const documentStore = {
|
|
|
2997
2057
|
sharedListener.dispose(), subscriptions.forEach((subscription) => subscription.unsubscribe());
|
|
2998
2058
|
};
|
|
2999
2059
|
}
|
|
3000
|
-
};
|
|
2060
|
+
});
|
|
3001
2061
|
function getDocumentState(...args) {
|
|
3002
2062
|
return _getDocumentState(...args);
|
|
3003
2063
|
}
|
|
3004
|
-
const _getDocumentState =
|
|
2064
|
+
const _getDocumentState = bindActionByResource(
|
|
3005
2065
|
documentStore,
|
|
3006
2066
|
createStateSourceAction({
|
|
3007
2067
|
selector: ({ state: { error, documentStates } }, options) => {
|
|
3008
|
-
const { documentId, path, liveEdit } = options;
|
|
2068
|
+
const { documentId: docId, path, liveEdit, perspective } = options, documentId = DocumentId(docId);
|
|
3009
2069
|
if (error) throw error;
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
if (
|
|
3016
|
-
|
|
3017
|
-
|
|
2070
|
+
let document;
|
|
2071
|
+
if (liveEdit)
|
|
2072
|
+
document = documentStates[documentId]?.local;
|
|
2073
|
+
else {
|
|
2074
|
+
let version;
|
|
2075
|
+
if (isReleasePerspective(perspective)) {
|
|
2076
|
+
const versionId = getVersionId(documentId, perspective.releaseName);
|
|
2077
|
+
if (version = documentStates[versionId]?.local, version === void 0) return;
|
|
2078
|
+
}
|
|
2079
|
+
const draft = documentStates[getDraftId(documentId)]?.local, published = documentStates[getPublishedId(documentId)]?.local;
|
|
2080
|
+
if (draft === void 0 || published === void 0) return;
|
|
2081
|
+
document = version ?? draft ?? published;
|
|
3018
2082
|
}
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
const document2 = draft ?? published;
|
|
3022
|
-
if (!path) return document2;
|
|
3023
|
-
const result = jsonMatch(document2, path).next();
|
|
2083
|
+
if (!path) return document;
|
|
2084
|
+
const result = jsonMatch(document, path).next();
|
|
3024
2085
|
if (result.done) return;
|
|
3025
2086
|
const { value } = result.value;
|
|
3026
2087
|
return value;
|
|
3027
2088
|
},
|
|
3028
|
-
onSubscribe: (context, options) => manageSubscriberIds(context, options
|
|
2089
|
+
onSubscribe: (context, options) => manageSubscriberIds(context, [options])
|
|
3029
2090
|
})
|
|
3030
2091
|
);
|
|
3031
2092
|
function resolveDocument(...args) {
|
|
3032
2093
|
return _resolveDocument(...args);
|
|
3033
2094
|
}
|
|
3034
|
-
const _resolveDocument =
|
|
2095
|
+
const _resolveDocument = bindActionByResource(
|
|
3035
2096
|
documentStore,
|
|
3036
2097
|
({ instance }, docHandle) => firstValueFrom(
|
|
3037
2098
|
getDocumentState(instance, {
|
|
3038
2099
|
...docHandle,
|
|
3039
2100
|
path: void 0
|
|
3040
|
-
}).observable.pipe(filter((i) => i !== void 0))
|
|
2101
|
+
}).observable.pipe(filter$1((i) => i !== void 0))
|
|
3041
2102
|
)
|
|
3042
|
-
), getDocumentSyncStatus =
|
|
2103
|
+
), getDocumentSyncStatus = bindActionByResource(
|
|
3043
2104
|
documentStore,
|
|
3044
2105
|
createStateSourceAction({
|
|
3045
2106
|
selector: ({ state: { error, documentStates: documents, outgoing, applied, queued } }, doc) => {
|
|
3046
|
-
const documentId = typeof doc == "string" ? doc : doc.documentId;
|
|
2107
|
+
const documentId = DocumentId(typeof doc == "string" ? doc : doc.documentId);
|
|
3047
2108
|
if (error) throw error;
|
|
3048
|
-
if (doc.liveEdit)
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
2109
|
+
if (doc.liveEdit) {
|
|
2110
|
+
if (documents[documentId] === void 0) return;
|
|
2111
|
+
} else {
|
|
2112
|
+
const version = isReleasePerspective(doc.perspective) ? documents[getVersionId(documentId, doc.perspective.releaseName)] : void 0;
|
|
2113
|
+
if (isReleasePerspective(doc.perspective) && version === void 0) return;
|
|
2114
|
+
const draft = documents[getDraftId(documentId)], published = documents[getPublishedId(documentId)];
|
|
2115
|
+
if (draft === void 0 || published === void 0) return;
|
|
2116
|
+
}
|
|
2117
|
+
return !queued.length && !applied.length && !outgoing;
|
|
3053
2118
|
},
|
|
3054
|
-
onSubscribe: (context, doc) => manageSubscriberIds(context, doc
|
|
2119
|
+
onSubscribe: (context, doc) => manageSubscriberIds(context, [doc])
|
|
3055
2120
|
})
|
|
3056
|
-
), getPermissionsState =
|
|
2121
|
+
), getPermissionsState = bindActionByResource(
|
|
3057
2122
|
documentStore,
|
|
3058
2123
|
createStateSourceAction({
|
|
3059
2124
|
selector: calculatePermissions,
|
|
3060
|
-
onSubscribe: (context, { actions }) =>
|
|
2125
|
+
onSubscribe: (context, { actions }) => {
|
|
2126
|
+
manageSubscriberIds(context, actions);
|
|
2127
|
+
}
|
|
3061
2128
|
})
|
|
3062
|
-
), resolvePermissions =
|
|
2129
|
+
), resolvePermissions = bindActionByResource(
|
|
3063
2130
|
documentStore,
|
|
3064
2131
|
({ instance }, options) => firstValueFrom(
|
|
3065
|
-
getPermissionsState(instance, options).observable.pipe(filter((i) => i !== void 0))
|
|
2132
|
+
getPermissionsState(instance, options).observable.pipe(filter$1((i) => i !== void 0))
|
|
3066
2133
|
)
|
|
3067
|
-
), subscribeDocumentEvents =
|
|
2134
|
+
), subscribeDocumentEvents = bindActionByResource(
|
|
3068
2135
|
documentStore,
|
|
3069
|
-
({ state },
|
|
3070
|
-
const { events } = state.get(), subscription = events.subscribe(eventHandler);
|
|
2136
|
+
({ state }, options) => {
|
|
2137
|
+
const { events } = state.get(), subscription = events.subscribe(options.eventHandler);
|
|
3071
2138
|
return () => subscription.unsubscribe();
|
|
3072
2139
|
}
|
|
3073
|
-
), subscribeToQueuedAndApplyNextTransaction = ({
|
|
2140
|
+
), subscribeToQueuedAndApplyNextTransaction = ({
|
|
2141
|
+
state
|
|
2142
|
+
}) => {
|
|
3074
2143
|
const { events } = state.get();
|
|
3075
2144
|
return state.observable.pipe(
|
|
3076
|
-
map(applyFirstQueuedTransaction),
|
|
2145
|
+
map$1(applyFirstQueuedTransaction),
|
|
3077
2146
|
distinctUntilChanged(),
|
|
3078
2147
|
tap$1((next) => state.set("applyFirstQueuedTransaction", next)),
|
|
3079
2148
|
catchError$1((error, caught) => {
|
|
@@ -3093,7 +2162,8 @@ const _resolveDocument = bindActionByDataset(
|
|
|
3093
2162
|
).subscribe({ error: (error) => state.set("setError", { error }) });
|
|
3094
2163
|
}, subscribeToAppliedAndSubmitNextTransaction = ({
|
|
3095
2164
|
state,
|
|
3096
|
-
instance
|
|
2165
|
+
instance,
|
|
2166
|
+
key: { resource }
|
|
3097
2167
|
}) => {
|
|
3098
2168
|
const { events } = state.get();
|
|
3099
2169
|
return state.observable.pipe(
|
|
@@ -3108,19 +2178,41 @@ const _resolveDocument = bindActionByDataset(
|
|
|
3108
2178
|
),
|
|
3109
2179
|
{ leading: !1, trailing: !0 }
|
|
3110
2180
|
),
|
|
3111
|
-
map(transitionAppliedTransactionsToOutgoing),
|
|
2181
|
+
map$1(transitionAppliedTransactionsToOutgoing),
|
|
3112
2182
|
distinctUntilChanged((a, b) => a.outgoing?.transactionId === b.outgoing?.transactionId),
|
|
3113
2183
|
tap$1((next) => state.set("transitionAppliedTransactionsToOutgoing", next)),
|
|
3114
|
-
map((s) => s.outgoing),
|
|
2184
|
+
map$1((s) => s.outgoing),
|
|
3115
2185
|
distinctUntilChanged(),
|
|
3116
|
-
withLatestFrom(
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
)
|
|
2186
|
+
withLatestFrom(
|
|
2187
|
+
getClientState(instance, {
|
|
2188
|
+
apiVersion: API_VERSION$2,
|
|
2189
|
+
// TODO: remove in v3 when we're ready for everything to be queried via resource
|
|
2190
|
+
resource: resource && !isDatasetResource(resource) ? resource : void 0
|
|
2191
|
+
}).observable
|
|
2192
|
+
),
|
|
2193
|
+
concatMap(([outgoing, client]) => {
|
|
2194
|
+
if (!outgoing) return EMPTY;
|
|
2195
|
+
const revertOnError = catchError$1((error) => {
|
|
2196
|
+
state.set("revertOutgoingTransaction", revertOutgoingTransaction);
|
|
2197
|
+
const message = error instanceof Error ? error.message : "Request failed";
|
|
2198
|
+
return events.next({ type: "reverted", message, outgoing, error }), EMPTY;
|
|
2199
|
+
}), toResult = map$1((result) => ({
|
|
2200
|
+
result,
|
|
2201
|
+
outgoing
|
|
2202
|
+
}));
|
|
2203
|
+
return outgoing.actions.some((action) => action.liveEdit) ? client.observable.mutate(outgoing.outgoingMutations, {
|
|
2204
|
+
transactionId: outgoing.transactionId,
|
|
2205
|
+
visibility: "async",
|
|
2206
|
+
returnDocuments: !1,
|
|
2207
|
+
returnFirst: !1,
|
|
2208
|
+
tag: "document.mutate",
|
|
2209
|
+
skipCrossDatasetReferenceValidation: !0
|
|
2210
|
+
}).pipe(revertOnError, toResult) : client.observable.action(outgoing.outgoingActions, {
|
|
2211
|
+
transactionId: outgoing.transactionId,
|
|
2212
|
+
skipCrossDatasetReferenceValidation: !0,
|
|
2213
|
+
tag: "document.action"
|
|
2214
|
+
}).pipe(revertOnError, toResult);
|
|
2215
|
+
}),
|
|
3124
2216
|
tap$1(({ outgoing, result }) => {
|
|
3125
2217
|
state.set("cleanupOutgoingTransaction", cleanupOutgoingTransaction);
|
|
3126
2218
|
for (const e of getDocumentEvents(outgoing)) events.next(e);
|
|
@@ -3130,8 +2222,8 @@ const _resolveDocument = bindActionByDataset(
|
|
|
3130
2222
|
}, subscribeToSubscriptionsAndListenToDocuments = (context) => {
|
|
3131
2223
|
const { state } = context, { events } = state.get();
|
|
3132
2224
|
return state.observable.pipe(
|
|
3133
|
-
filter((s) => !!s.grants),
|
|
3134
|
-
map((s) => Object.keys(s.documentStates)),
|
|
2225
|
+
filter$1((s) => !!s.grants),
|
|
2226
|
+
map$1((s) => Object.keys(s.documentStates)),
|
|
3135
2227
|
distinctUntilChanged((curr, next) => {
|
|
3136
2228
|
if (curr.length !== next.length) return !1;
|
|
3137
2229
|
const currSet = new Set(curr);
|
|
@@ -3144,7 +2236,7 @@ const _resolveDocument = bindActionByDataset(
|
|
|
3144
2236
|
...added.map((id) => ({ id, add: !0 })),
|
|
3145
2237
|
...removed.map((id) => ({ id, add: !1 }))
|
|
3146
2238
|
].sort((a, b) => {
|
|
3147
|
-
const aIsDraft = a.id === getDraftId(a.id), bIsDraft = b.id === getDraftId(b.id);
|
|
2239
|
+
const aIsDraft = a.id === getDraftId(DocumentId(a.id)), bIsDraft = b.id === getDraftId(DocumentId(b.id));
|
|
3148
2240
|
return aIsDraft && bIsDraft ? a.id.localeCompare(b.id, "en-US") : aIsDraft ? -1 : bIsDraft ? 1 : a.id.localeCompare(b.id, "en-US");
|
|
3149
2241
|
});
|
|
3150
2242
|
return of(...changes);
|
|
@@ -3169,45 +2261,58 @@ const _resolveDocument = bindActionByDataset(
|
|
|
3169
2261
|
}, subscribeToClientAndFetchDatasetAcl = ({
|
|
3170
2262
|
instance,
|
|
3171
2263
|
state,
|
|
3172
|
-
key: {
|
|
3173
|
-
}) =>
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
});
|
|
2264
|
+
key: { resource }
|
|
2265
|
+
}) => {
|
|
2266
|
+
const clientOptions = { apiVersion: API_VERSION$2 };
|
|
2267
|
+
resource && !isDatasetResource(resource) && (clientOptions.resource = resource);
|
|
2268
|
+
let uri;
|
|
2269
|
+
if (resource && isDatasetResource(resource))
|
|
2270
|
+
uri = `/projects/${resource.projectId}/datasets/${resource.dataset}/acl`;
|
|
2271
|
+
else if (resource && isMediaLibraryResource(resource))
|
|
2272
|
+
uri = `/media-libraries/${resource.mediaLibraryId}/acl`;
|
|
2273
|
+
else if (resource && isCanvasResource(resource))
|
|
2274
|
+
uri = `/canvases/${resource.canvasId}/acl`;
|
|
2275
|
+
else
|
|
2276
|
+
throw new Error(`Received invalid resource: ${JSON.stringify(resource)}`);
|
|
2277
|
+
return getClientState(instance, clientOptions).observable.pipe(
|
|
2278
|
+
switchMap(
|
|
2279
|
+
(client) => client.observable.request({
|
|
2280
|
+
uri,
|
|
2281
|
+
tag: "acl.get",
|
|
2282
|
+
withCredentials: !0
|
|
2283
|
+
})
|
|
2284
|
+
),
|
|
2285
|
+
tap$1((datasetAcl) => state.set("setGrants", { grants: createGrantsLookup(datasetAcl) }))
|
|
2286
|
+
).subscribe({
|
|
2287
|
+
error: (error) => state.set("setError", { error })
|
|
2288
|
+
});
|
|
2289
|
+
};
|
|
3185
2290
|
function applyDocumentActions(...args) {
|
|
3186
2291
|
return boundApplyDocumentActions(...args);
|
|
3187
2292
|
}
|
|
3188
|
-
const boundApplyDocumentActions =
|
|
2293
|
+
const boundApplyDocumentActions = bindActionByResource(documentStore, _applyDocumentActions);
|
|
3189
2294
|
async function _applyDocumentActions({ state }, { actions, transactionId = crypto.randomUUID(), disableBatching }) {
|
|
3190
2295
|
const { events } = state.get(), transaction = {
|
|
3191
2296
|
transactionId,
|
|
3192
2297
|
actions,
|
|
3193
2298
|
...disableBatching && { disableBatching }
|
|
3194
2299
|
}, fatalError$ = state.observable.pipe(
|
|
3195
|
-
map((s) => s.error),
|
|
2300
|
+
map$1((s) => s.error),
|
|
3196
2301
|
first$1(Boolean),
|
|
3197
|
-
map((error) => ({ type: "error", error }))
|
|
2302
|
+
map$1((error) => ({ type: "error", error }))
|
|
3198
2303
|
), transactionError$ = events.pipe(
|
|
3199
|
-
filter((e) => e.type === "error"),
|
|
2304
|
+
filter$1((e) => e.type === "error"),
|
|
3200
2305
|
first$1((e) => e.transactionId === transactionId)
|
|
3201
2306
|
), appliedTransaction$ = state.observable.pipe(
|
|
3202
|
-
map((s) => s.applied),
|
|
2307
|
+
map$1((s) => s.applied),
|
|
3203
2308
|
distinctUntilChanged(),
|
|
3204
|
-
map((applied) => applied.find((t) => t.transactionId === transactionId)),
|
|
2309
|
+
map$1((applied) => applied.find((t) => t.transactionId === transactionId)),
|
|
3205
2310
|
first$1(Boolean)
|
|
3206
2311
|
), successfulTransaction$ = events.pipe(
|
|
3207
|
-
filter((e) => e.type === "accepted"),
|
|
2312
|
+
filter$1((e) => e.type === "accepted"),
|
|
3208
2313
|
first$1((e) => e.outgoing.batchedTransactionIds.includes(transactionId))
|
|
3209
2314
|
), rejectedTransaction$ = events.pipe(
|
|
3210
|
-
filter((e) => e.type === "reverted"),
|
|
2315
|
+
filter$1((e) => e.type === "reverted"),
|
|
3211
2316
|
first$1((e) => e.outgoing.batchedTransactionIds.includes(transactionId))
|
|
3212
2317
|
), appliedTransactionOrError = firstValueFrom(
|
|
3213
2318
|
race([fatalError$, transactionError$, appliedTransaction$])
|
|
@@ -3262,7 +2367,7 @@ const favorites = createFetcherStore({
|
|
|
3262
2367
|
}
|
|
3263
2368
|
};
|
|
3264
2369
|
return nodeStateSource.observable.pipe(
|
|
3265
|
-
filter((nodeState) => !!nodeState),
|
|
2370
|
+
filter$1((nodeState) => !!nodeState),
|
|
3266
2371
|
// Only proceed when connected
|
|
3267
2372
|
shareReplay(1),
|
|
3268
2373
|
switchMap((nodeState) => {
|
|
@@ -3274,55 +2379,21 @@ const favorites = createFetcherStore({
|
|
|
3274
2379
|
payload
|
|
3275
2380
|
)
|
|
3276
2381
|
).pipe(
|
|
3277
|
-
map((response) => ({ isFavorited: response.isFavorited })),
|
|
2382
|
+
map$1((response) => ({ isFavorited: response.isFavorited })),
|
|
3278
2383
|
catchError$1((err) => (console.error("Favorites service connection error", err), of({ isFavorited: !1 })))
|
|
3279
2384
|
);
|
|
3280
2385
|
})
|
|
3281
2386
|
);
|
|
3282
2387
|
}
|
|
3283
|
-
}), getFavoritesState = favorites.getState, resolveFavoritesState = favorites.resolveState,
|
|
3284
|
-
resourceType,
|
|
3285
|
-
organizationId,
|
|
3286
|
-
batchSize = DEFAULT_USERS_BATCH_SIZE,
|
|
3287
|
-
projectId = instance.config.projectId,
|
|
3288
|
-
userId
|
|
3289
|
-
} = {}) => JSON.stringify({
|
|
3290
|
-
resourceType,
|
|
3291
|
-
organizationId,
|
|
3292
|
-
batchSize,
|
|
3293
|
-
projectId,
|
|
3294
|
-
userId
|
|
3295
|
-
}), parseUsersKey = (key) => JSON.parse(key), addSubscription = (subscriptionId, key) => (prev) => {
|
|
3296
|
-
const group = prev.users[key], subscriptions = [...group?.subscriptions ?? [], subscriptionId];
|
|
3297
|
-
return { ...prev, users: { ...prev.users, [key]: { ...group, subscriptions } } };
|
|
3298
|
-
}, removeSubscription = (subscriptionId, key) => (prev) => {
|
|
3299
|
-
const group = prev.users[key];
|
|
3300
|
-
if (!group) return prev;
|
|
3301
|
-
const subscriptions = group.subscriptions.filter((id) => id !== subscriptionId);
|
|
3302
|
-
return subscriptions.length ? { ...prev, users: { ...prev.users, [key]: { ...group, subscriptions } } } : { ...prev, users: omit(prev.users, key) };
|
|
3303
|
-
}, setUsersData = (key, { data, nextCursor, totalCount }) => (prev) => {
|
|
3304
|
-
const group = prev.users[key];
|
|
3305
|
-
if (!group) return prev;
|
|
3306
|
-
const users = [...group.users ?? [], ...data];
|
|
3307
|
-
return { ...prev, users: { ...prev.users, [key]: { ...group, users, totalCount, nextCursor } } };
|
|
3308
|
-
}, updateLastLoadMoreRequest = (timestamp, key) => (prev) => {
|
|
3309
|
-
const group = prev.users[key];
|
|
3310
|
-
return group ? { ...prev, users: { ...prev.users, [key]: { ...group, lastLoadMoreRequest: timestamp } } } : prev;
|
|
3311
|
-
}, setUsersError = (key, error) => (prev) => {
|
|
3312
|
-
const group = prev.users[key];
|
|
3313
|
-
return group ? { ...prev, users: { ...prev.users, [key]: { ...group, error } } } : prev;
|
|
3314
|
-
}, cancelRequest = (key) => (prev) => {
|
|
3315
|
-
const group = prev.users[key];
|
|
3316
|
-
return !group || group.subscriptions.length ? prev : { ...prev, users: omit(prev.users, key) };
|
|
3317
|
-
}, initializeRequest = (key) => (prev) => prev.users[key] ? prev : { ...prev, users: { ...prev.users, [key]: { subscriptions: [] } } }, usersStore = {
|
|
2388
|
+
}), getFavoritesState = favorites.getState, resolveFavoritesState = favorites.resolveState, usersStore = defineStore({
|
|
3318
2389
|
name: "UsersStore",
|
|
3319
2390
|
getInitialState: () => ({ users: {} }),
|
|
3320
2391
|
initialize: (context) => {
|
|
3321
2392
|
const subscription = listenForLoadMoreAndFetch(context);
|
|
3322
2393
|
return () => subscription.unsubscribe();
|
|
3323
2394
|
}
|
|
3324
|
-
}, errorHandler
|
|
3325
|
-
map((s) => new Set(Object.keys(s.users))),
|
|
2395
|
+
}), errorHandler = (state) => (error) => state.set("setError", { error }), listenForLoadMoreAndFetch = ({ state, instance }) => state.observable.pipe(
|
|
2396
|
+
map$1((s) => new Set(Object.keys(s.users))),
|
|
3326
2397
|
distinctUntilChanged((curr, next) => curr.size !== next.size ? !1 : Array.from(next).every((i) => curr.has(i))),
|
|
3327
2398
|
startWith$1(/* @__PURE__ */ new Set()),
|
|
3328
2399
|
pairwise$1(),
|
|
@@ -3349,9 +2420,10 @@ const favorites = createFetcherStore({
|
|
|
3349
2420
|
useProjectHostname: !0
|
|
3350
2421
|
}).observable.request({
|
|
3351
2422
|
method: "GET",
|
|
3352
|
-
uri: `/users/${userId}
|
|
2423
|
+
uri: `/users/${userId}`,
|
|
2424
|
+
tag: "users.get"
|
|
3353
2425
|
}).pipe(
|
|
3354
|
-
map((user) => ({
|
|
2426
|
+
map$1((user) => ({
|
|
3355
2427
|
data: [{
|
|
3356
2428
|
sanityUserId: user.sanityUserId,
|
|
3357
2429
|
profile: {
|
|
@@ -3379,13 +2451,14 @@ const favorites = createFetcherStore({
|
|
|
3379
2451
|
);
|
|
3380
2452
|
const scope = userId.startsWith("g") ? "global" : void 0, client = getClient(instance, {
|
|
3381
2453
|
scope,
|
|
3382
|
-
apiVersion: API_VERSION$
|
|
2454
|
+
apiVersion: API_VERSION$6
|
|
3383
2455
|
}), resourceType2 = options.resourceType || "project", resourceId = resourceType2 === "organization" ? options.organizationId : options.projectId;
|
|
3384
2456
|
return resourceId ? client.observable.request({
|
|
3385
2457
|
method: "GET",
|
|
3386
|
-
uri: `access/${resourceType2}/${resourceId}/users/${userId}
|
|
2458
|
+
uri: `access/${resourceType2}/${resourceId}/users/${userId}`,
|
|
2459
|
+
tag: "users.get"
|
|
3387
2460
|
}).pipe(
|
|
3388
|
-
map((response) => "sanityUserId" in response ? {
|
|
2461
|
+
map$1((response) => "sanityUserId" in response ? {
|
|
3389
2462
|
data: [response],
|
|
3390
2463
|
totalCount: 1,
|
|
3391
2464
|
nextCursor: null
|
|
@@ -3395,17 +2468,17 @@ const favorites = createFetcherStore({
|
|
|
3395
2468
|
) : throwError(() => new Error("An organizationId or a projectId is required"));
|
|
3396
2469
|
}
|
|
3397
2470
|
const projectId = options.projectId, resourceType = options.resourceType ?? (options.organizationId ? "organization" : projectId ? "project" : "organization"), organizationId$ = options.organizationId ? of(options.organizationId) : getDashboardOrganizationId$1(instance).observable.pipe(
|
|
3398
|
-
filter((i) => typeof i == "string")
|
|
3399
|
-
), resource$ = resourceType === "project" ? projectId ? of({ type: "project", id: projectId }) : throwError(() => new Error("Project ID required for this API.")) : organizationId$.pipe(map((id) => ({ type: "organization", id }))), client$ = getClientState(instance, {
|
|
2471
|
+
filter$1((i) => typeof i == "string")
|
|
2472
|
+
), resource$ = resourceType === "project" ? projectId ? of({ type: "project", id: projectId }) : throwError(() => new Error("Project ID required for this API.")) : organizationId$.pipe(map$1((id) => ({ type: "organization", id }))), client$ = getClientState(instance, {
|
|
3400
2473
|
scope: "global",
|
|
3401
|
-
apiVersion: API_VERSION$
|
|
2474
|
+
apiVersion: API_VERSION$6
|
|
3402
2475
|
}).observable, loadMore$ = state.observable.pipe(
|
|
3403
|
-
map((s) => s.users[group$.key]?.lastLoadMoreRequest),
|
|
2476
|
+
map$1((s) => s.users[group$.key]?.lastLoadMoreRequest),
|
|
3404
2477
|
distinctUntilChanged()
|
|
3405
2478
|
), cursor$ = state.observable.pipe(
|
|
3406
|
-
map((s) => s.users[group$.key]?.nextCursor),
|
|
2479
|
+
map$1((s) => s.users[group$.key]?.nextCursor),
|
|
3407
2480
|
distinctUntilChanged(),
|
|
3408
|
-
filter((cursor) => cursor !== null)
|
|
2481
|
+
filter$1((cursor) => cursor !== null)
|
|
3409
2482
|
);
|
|
3410
2483
|
return combineLatest([resource$, client$, loadMore$]).pipe(
|
|
3411
2484
|
withLatestFrom(cursor$),
|
|
@@ -3413,6 +2486,7 @@ const favorites = createFetcherStore({
|
|
|
3413
2486
|
([[resource, client], cursor]) => client.observable.request({
|
|
3414
2487
|
method: "GET",
|
|
3415
2488
|
uri: `access/${resource.type}/${resource.id}/users`,
|
|
2489
|
+
tag: "users.list",
|
|
3416
2490
|
query: cursor ? { nextCursor: cursor, limit: batchSize.toString() } : { limit: batchSize.toString() }
|
|
3417
2491
|
})
|
|
3418
2492
|
),
|
|
@@ -3422,7 +2496,7 @@ const favorites = createFetcherStore({
|
|
|
3422
2496
|
})
|
|
3423
2497
|
)
|
|
3424
2498
|
)
|
|
3425
|
-
).subscribe({ error: errorHandler
|
|
2499
|
+
).subscribe({ error: errorHandler(state) }), getUsersState = bindActionGlobally(
|
|
3426
2500
|
usersStore,
|
|
3427
2501
|
createStateSourceAction({
|
|
3428
2502
|
selector: createSelector(
|
|
@@ -3441,7 +2515,7 @@ const favorites = createFetcherStore({
|
|
|
3441
2515
|
onSubscribe: ({ instance, state }, options) => {
|
|
3442
2516
|
const subscriptionId = insecureRandomId(), key = getUsersKey(instance, options);
|
|
3443
2517
|
return state.set("addSubscription", addSubscription(subscriptionId, key)), () => {
|
|
3444
|
-
|
|
2518
|
+
setCleanupTimeout(
|
|
3445
2519
|
() => state.set("removeSubscription", removeSubscription(subscriptionId, key)),
|
|
3446
2520
|
USERS_STATE_CLEAR_DELAY
|
|
3447
2521
|
);
|
|
@@ -3465,7 +2539,7 @@ const favorites = createFetcherStore({
|
|
|
3465
2539
|
) : NEVER;
|
|
3466
2540
|
state.set("initializeRequest", initializeRequest(key));
|
|
3467
2541
|
const resolved$ = state.observable.pipe(
|
|
3468
|
-
map(getCurrent),
|
|
2542
|
+
map$1(getCurrent),
|
|
3469
2543
|
first$1((i) => i !== void 0)
|
|
3470
2544
|
);
|
|
3471
2545
|
return firstValueFrom(race([resolved$, aborted$]));
|
|
@@ -3480,7 +2554,7 @@ const favorites = createFetcherStore({
|
|
|
3480
2554
|
throw new Error("No more users available to load for this resource.");
|
|
3481
2555
|
const promise = firstValueFrom(
|
|
3482
2556
|
users.observable.pipe(
|
|
3483
|
-
filter((i) => i !== void 0),
|
|
2557
|
+
filter$1((i) => i !== void 0),
|
|
3484
2558
|
skip(1)
|
|
3485
2559
|
)
|
|
3486
2560
|
), timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -3489,7 +2563,7 @@ const favorites = createFetcherStore({
|
|
|
3489
2563
|
), getUserState = bindActionGlobally(
|
|
3490
2564
|
usersStore,
|
|
3491
2565
|
({ instance }, { userId, ...options }) => getUsersState(instance, { userId, ...options }).observable.pipe(
|
|
3492
|
-
map((res) => res?.data[0]),
|
|
2566
|
+
map$1((res) => res?.data[0]),
|
|
3493
2567
|
distinctUntilChanged((a, b) => a?.profile.updatedAt === b?.profile.updatedAt)
|
|
3494
2568
|
)
|
|
3495
2569
|
), resolveUser = bindActionGlobally(
|
|
@@ -3500,7 +2574,20 @@ const favorites = createFetcherStore({
|
|
|
3500
2574
|
}))?.data[0]
|
|
3501
2575
|
);
|
|
3502
2576
|
function getBifurClient(client, token$) {
|
|
3503
|
-
const bifurVersionedClient = client.withConfig({ apiVersion: "2022-06-30" }), {
|
|
2577
|
+
const bifurVersionedClient = client.withConfig({ apiVersion: "2022-06-30" }), {
|
|
2578
|
+
resource,
|
|
2579
|
+
dataset,
|
|
2580
|
+
url: baseUrl,
|
|
2581
|
+
requestTagPrefix = "sanity.sdk.presence"
|
|
2582
|
+
} = bifurVersionedClient.config();
|
|
2583
|
+
let resourcePath;
|
|
2584
|
+
if (resource?.type === "canvas")
|
|
2585
|
+
resourcePath = `canvases/${resource.id}`;
|
|
2586
|
+
else if (dataset)
|
|
2587
|
+
resourcePath = dataset;
|
|
2588
|
+
else
|
|
2589
|
+
throw new Error("Unable to determine presence URL: no canvas resource or dataset configured");
|
|
2590
|
+
const urlWithTag = `${`${baseUrl}/socket/${resourcePath}`.replace(/^http/, "ws")}?tag=${requestTagPrefix}`;
|
|
3504
2591
|
return fromUrl(urlWithTag, { token$ });
|
|
3505
2592
|
}
|
|
3506
2593
|
const handleIncomingMessage = (event) => {
|
|
@@ -3532,7 +2619,7 @@ const handleIncomingMessage = (event) => {
|
|
|
3532
2619
|
throw new Error(`Got unknown presence event: ${JSON.stringify(event)}`);
|
|
3533
2620
|
}
|
|
3534
2621
|
}, createBifurTransport = (options) => {
|
|
3535
|
-
const { client, token$, sessionId } = options, bifur = getBifurClient(client, token$), incomingEvents$ = bifur.listen("presence").pipe(map
|
|
2622
|
+
const { client, token$, sessionId } = options, bifur = getBifurClient(client, token$), incomingEvents$ = bifur.listen("presence").pipe(map(handleIncomingMessage)), dispatchMessage = (message) => {
|
|
3536
2623
|
switch (message.type) {
|
|
3537
2624
|
case "rollCall":
|
|
3538
2625
|
return bifur.request("presence_rollcall", { session: sessionId });
|
|
@@ -3547,27 +2634,34 @@ const handleIncomingMessage = (event) => {
|
|
|
3547
2634
|
}
|
|
3548
2635
|
};
|
|
3549
2636
|
return typeof window < "u" && fromEvent(window, "beforeunload").pipe(switchMap$1(() => dispatchMessage({ type: "disconnect" }))).subscribe(), [incomingEvents$.pipe(share$1()), dispatchMessage];
|
|
3550
|
-
}, getInitialState = () => ({
|
|
2637
|
+
}, PRESENCE_API_VERSION = "2026-03-30", getInitialState = () => ({
|
|
3551
2638
|
locations: /* @__PURE__ */ new Map(),
|
|
3552
2639
|
users: {}
|
|
3553
|
-
}), presenceStore = {
|
|
2640
|
+
}), presenceStore = defineStore({
|
|
3554
2641
|
name: "presence",
|
|
3555
2642
|
getInitialState,
|
|
3556
2643
|
initialize: (context) => {
|
|
3557
2644
|
const {
|
|
3558
2645
|
instance,
|
|
3559
2646
|
state,
|
|
3560
|
-
key: {
|
|
3561
|
-
} = context
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
2647
|
+
key: { resource }
|
|
2648
|
+
} = context;
|
|
2649
|
+
if (isMediaLibraryResource(resource))
|
|
2650
|
+
throw new Error("Presence is not supported for media library resources.");
|
|
2651
|
+
const sessionId = crypto.randomUUID(), client = isDatasetResource(resource) ? getClient(instance, {
|
|
2652
|
+
apiVersion: PRESENCE_API_VERSION,
|
|
2653
|
+
projectId: resource.projectId,
|
|
2654
|
+
dataset: resource.dataset,
|
|
2655
|
+
useProjectHostname: !0
|
|
2656
|
+
}) : getClient(instance, {
|
|
2657
|
+
apiVersion: PRESENCE_API_VERSION,
|
|
2658
|
+
resource
|
|
3565
2659
|
}), token$ = getTokenState(instance).observable.pipe(distinctUntilChanged()), [incomingEvents$, dispatch] = createBifurTransport({
|
|
3566
2660
|
client,
|
|
3567
2661
|
token$,
|
|
3568
2662
|
sessionId
|
|
3569
2663
|
}), subscription = new Subscription();
|
|
3570
|
-
|
|
2664
|
+
if (subscription.add(
|
|
3571
2665
|
incomingEvents$.subscribe((event) => {
|
|
3572
2666
|
"sessionId" in event && event.sessionId === sessionId || (event.type === "state" ? state.set("presence/state", (prevState) => {
|
|
3573
2667
|
const newLocations = new Map(prevState.locations);
|
|
@@ -3583,11 +2677,22 @@ const handleIncomingMessage = (event) => {
|
|
|
3583
2677
|
return newLocations.delete(event.sessionId), { ...prevState, locations: newLocations };
|
|
3584
2678
|
}));
|
|
3585
2679
|
})
|
|
3586
|
-
), dispatch({ type: "rollCall" }).subscribe(), ()
|
|
2680
|
+
), dispatch({ type: "rollCall" }).subscribe(), isCanvasResource(resource)) {
|
|
2681
|
+
const globalClient = getClient(instance, { apiVersion: PRESENCE_API_VERSION });
|
|
2682
|
+
subscription.add(
|
|
2683
|
+
globalClient.observable.request({
|
|
2684
|
+
uri: `/canvases/${resource.canvasId}`,
|
|
2685
|
+
tag: "canvases.get"
|
|
2686
|
+
}).pipe(catchError$1(() => EMPTY)).subscribe(({ organizationId }) => {
|
|
2687
|
+
state.set("presence/organizationId", (prev) => ({ ...prev, organizationId }));
|
|
2688
|
+
})
|
|
2689
|
+
);
|
|
2690
|
+
}
|
|
2691
|
+
return () => {
|
|
3587
2692
|
dispatch({ type: "disconnect" }).subscribe(), subscription.unsubscribe();
|
|
3588
2693
|
};
|
|
3589
2694
|
}
|
|
3590
|
-
}, selectLocations = (state) => state.locations, selectUsers = (state) => state.users, selectPresence = createSelector(
|
|
2695
|
+
}), selectLocations = (state) => state.locations, selectUsers = (state) => state.users, selectPresence = createSelector(
|
|
3591
2696
|
selectLocations,
|
|
3592
2697
|
selectUsers,
|
|
3593
2698
|
(locations, users) => Array.from(locations.entries()).map(([sessionId, { userId, locations: locs }]) => ({
|
|
@@ -3600,31 +2705,34 @@ const handleIncomingMessage = (event) => {
|
|
|
3600
2705
|
sessionId,
|
|
3601
2706
|
locations: locs
|
|
3602
2707
|
}))
|
|
3603
|
-
),
|
|
2708
|
+
), _getPresence = bindActionByResource(
|
|
3604
2709
|
presenceStore,
|
|
3605
2710
|
createStateSourceAction({
|
|
3606
|
-
selector: (context
|
|
3607
|
-
onSubscribe: (context
|
|
3608
|
-
const
|
|
3609
|
-
map(
|
|
2711
|
+
selector: (context) => selectPresence(context.state),
|
|
2712
|
+
onSubscribe: (context) => {
|
|
2713
|
+
const resource = context.key.resource, userIds$ = context.state.observable.pipe(
|
|
2714
|
+
map$1(
|
|
3610
2715
|
(state) => Array.from(state.locations.values()).map((l) => l.userId).filter((id) => !!id)
|
|
3611
2716
|
),
|
|
3612
2717
|
distinctUntilChanged((a, b) => a.length === b.length && a.every((v, i) => v === b[i]))
|
|
3613
|
-
).pipe(
|
|
3614
|
-
|
|
2718
|
+
), organizationId$ = isCanvasResource(resource) ? context.state.observable.pipe(
|
|
2719
|
+
map$1((s) => s.organizationId),
|
|
2720
|
+
filter$1((id) => id !== void 0),
|
|
2721
|
+
first$1()
|
|
2722
|
+
) : of(void 0), subscription = combineLatest([userIds$, organizationId$]).pipe(
|
|
2723
|
+
switchMap(([userIds, organizationId]) => {
|
|
3615
2724
|
if (userIds.length === 0)
|
|
3616
2725
|
return of([]);
|
|
3617
2726
|
const userObservables = userIds.map(
|
|
3618
2727
|
(userId) => getUserState(context.instance, {
|
|
3619
2728
|
userId,
|
|
3620
|
-
resourceType: "project",
|
|
3621
|
-
|
|
3622
|
-
}).pipe(filter((v) => !!v))
|
|
2729
|
+
...isDatasetResource(resource) ? { resourceType: "project", projectId: resource.projectId } : { resourceType: "organization", organizationId }
|
|
2730
|
+
}).pipe(filter$1((v) => !!v))
|
|
3623
2731
|
);
|
|
3624
2732
|
return combineLatest(userObservables);
|
|
3625
2733
|
})
|
|
3626
2734
|
).subscribe((users) => {
|
|
3627
|
-
|
|
2735
|
+
context.state.set("presence/users", (prevState) => ({
|
|
3628
2736
|
...prevState,
|
|
3629
2737
|
users: {
|
|
3630
2738
|
...prevState.users,
|
|
@@ -3636,489 +2744,16 @@ const handleIncomingMessage = (event) => {
|
|
|
3636
2744
|
}
|
|
3637
2745
|
})
|
|
3638
2746
|
);
|
|
3639
|
-
function
|
|
3640
|
-
return
|
|
3641
|
-
if (a.metadata.releaseType === "undecided" && b.metadata.releaseType !== "undecided")
|
|
3642
|
-
return -1;
|
|
3643
|
-
if (a.metadata.releaseType !== "undecided" && b.metadata.releaseType === "undecided")
|
|
3644
|
-
return 1;
|
|
3645
|
-
if (a.metadata.releaseType === "undecided" && b.metadata.releaseType === "undecided")
|
|
3646
|
-
return new Date(b._createdAt).getTime() - new Date(a._createdAt).getTime();
|
|
3647
|
-
if (a.metadata.releaseType === "scheduled" && b.metadata.releaseType === "scheduled") {
|
|
3648
|
-
const aPublishAt = a.publishAt || a.metadata.intendedPublishAt;
|
|
3649
|
-
if (!aPublishAt)
|
|
3650
|
-
return 1;
|
|
3651
|
-
const bPublishAt = b.publishAt || b.metadata.intendedPublishAt;
|
|
3652
|
-
return bPublishAt ? new Date(bPublishAt).getTime() - new Date(aPublishAt).getTime() : -1;
|
|
3653
|
-
}
|
|
3654
|
-
return a.metadata.releaseType === "asap" && b.metadata.releaseType !== "asap" ? 1 : a.metadata.releaseType !== "asap" && b.metadata.releaseType === "asap" ? -1 : a.metadata.releaseType === "asap" && b.metadata.releaseType === "asap" ? new Date(b._createdAt).getTime() - new Date(a._createdAt).getTime() : 0;
|
|
3655
|
-
});
|
|
2747
|
+
function getPresence(instance, params) {
|
|
2748
|
+
return _getPresence(instance, params ?? {});
|
|
3656
2749
|
}
|
|
3657
|
-
const ARCHIVED_RELEASE_STATES = ["archived", "published"], STABLE_EMPTY_RELEASES = [], releasesStore = {
|
|
3658
|
-
name: "Releases",
|
|
3659
|
-
getInitialState: () => ({
|
|
3660
|
-
activeReleases: void 0
|
|
3661
|
-
}),
|
|
3662
|
-
initialize: (context) => {
|
|
3663
|
-
const subscription = subscribeToReleases(context);
|
|
3664
|
-
return () => subscription.unsubscribe();
|
|
3665
|
-
}
|
|
3666
|
-
}, getActiveReleasesState = bindActionByDataset(
|
|
3667
|
-
releasesStore,
|
|
3668
|
-
createStateSourceAction({
|
|
3669
|
-
selector: ({ state }, _) => state.activeReleases
|
|
3670
|
-
})
|
|
3671
|
-
), RELEASES_QUERY = "releases::all()", subscribeToReleases = ({
|
|
3672
|
-
instance,
|
|
3673
|
-
state,
|
|
3674
|
-
key: { projectId, dataset }
|
|
3675
|
-
}) => {
|
|
3676
|
-
const { observable: releases$ } = getQueryState(instance, {
|
|
3677
|
-
query: RELEASES_QUERY,
|
|
3678
|
-
perspective: "raw",
|
|
3679
|
-
projectId,
|
|
3680
|
-
dataset,
|
|
3681
|
-
tag: "releases"
|
|
3682
|
-
});
|
|
3683
|
-
return releases$.pipe(
|
|
3684
|
-
map((releases) => {
|
|
3685
|
-
state.set("setActiveReleases", {
|
|
3686
|
-
activeReleases: sortReleases(releases ?? STABLE_EMPTY_RELEASES).filter((release) => !ARCHIVED_RELEASE_STATES.includes(release.state)).reverse()
|
|
3687
|
-
});
|
|
3688
|
-
})
|
|
3689
|
-
).subscribe({ error: (error) => state.set("setError", { error }) });
|
|
3690
|
-
}, DEFAULT_PERSPECTIVE = "drafts", optionsCache = /* @__PURE__ */ new Map(), selectInstancePerspective = (context, _) => context.instance.config.perspective, selectActiveReleases = (context) => context.state.activeReleases, selectOptions = (_context, options) => options, memoizedOptionsSelector = createSelector(
|
|
3691
|
-
[selectActiveReleases, selectOptions],
|
|
3692
|
-
(activeReleases, options) => {
|
|
3693
|
-
if (!options || !activeReleases) return options;
|
|
3694
|
-
const releaseIds = activeReleases.map((release) => release._id).join(",");
|
|
3695
|
-
let nestedCache = optionsCache.get(releaseIds);
|
|
3696
|
-
nestedCache || (nestedCache = /* @__PURE__ */ new Map(), optionsCache.set(releaseIds, nestedCache));
|
|
3697
|
-
const optionsKey = JSON.stringify(options);
|
|
3698
|
-
let cachedOptions = nestedCache.get(optionsKey);
|
|
3699
|
-
return cachedOptions || (cachedOptions = options, nestedCache.set(optionsKey, cachedOptions)), cachedOptions;
|
|
3700
|
-
}
|
|
3701
|
-
), _getPerspectiveStateSelector = createStateSourceAction({
|
|
3702
|
-
selector: createSelector(
|
|
3703
|
-
[selectInstancePerspective, selectActiveReleases, memoizedOptionsSelector],
|
|
3704
|
-
(instancePerspective, activeReleases, memoizedOptions) => {
|
|
3705
|
-
const perspective = memoizedOptions?.perspective ?? instancePerspective ?? DEFAULT_PERSPECTIVE;
|
|
3706
|
-
if (!isReleasePerspective(perspective)) return perspective;
|
|
3707
|
-
if (!activeReleases || activeReleases.length === 0) return;
|
|
3708
|
-
const releaseNames = sortReleases(activeReleases).map((release) => release.name), index = releaseNames.findIndex((name) => name === perspective.releaseName);
|
|
3709
|
-
if (index < 0)
|
|
3710
|
-
throw new Error(`Release "${perspective.releaseName}" not found in active releases`);
|
|
3711
|
-
return ["drafts", ...releaseNames.slice(0, index + 1)].filter((name) => !perspective.excludedPerspectives?.includes(name)).reverse();
|
|
3712
|
-
}
|
|
3713
|
-
)
|
|
3714
|
-
});
|
|
3715
|
-
let _boundGetPerspectiveState;
|
|
3716
|
-
const getPerspectiveState = (...args) => (_boundGetPerspectiveState || (_boundGetPerspectiveState = bindActionByDataset(
|
|
3717
|
-
releasesStore,
|
|
3718
|
-
_getPerspectiveStateSelector
|
|
3719
|
-
)), _boundGetPerspectiveState(...args)), QUERY_STATE_CLEAR_DELAY = 1e3, QUERY_STORE_API_VERSION = "v2025-05-06", QUERY_STORE_DEFAULT_PERSPECTIVE = "drafts", setQueryError = (key, error) => (prev) => {
|
|
3720
|
-
const prevQuery = prev.queries[key];
|
|
3721
|
-
return prevQuery ? { ...prev, queries: { ...prev.queries, [key]: { ...prevQuery, error } } } : prev;
|
|
3722
|
-
}, setQueryData = (key, result, syncTags) => (prev) => {
|
|
3723
|
-
const prevQuery = prev.queries[key];
|
|
3724
|
-
return prevQuery ? {
|
|
3725
|
-
...prev,
|
|
3726
|
-
queries: { ...prev.queries, [key]: { ...prevQuery, result: result ?? null, syncTags } }
|
|
3727
|
-
} : prev;
|
|
3728
|
-
}, setLastLiveEventId = (key, lastLiveEventId) => (prev) => {
|
|
3729
|
-
const prevQuery = prev.queries[key];
|
|
3730
|
-
return prevQuery ? { ...prev, queries: { ...prev.queries, [key]: { ...prevQuery, lastLiveEventId } } } : prev;
|
|
3731
|
-
}, addSubscriber = (key, subscriptionId) => (prev) => {
|
|
3732
|
-
const prevQuery = prev.queries[key], subscribers = [...prevQuery?.subscribers ?? [], subscriptionId];
|
|
3733
|
-
return { ...prev, queries: { ...prev.queries, [key]: { ...prevQuery, subscribers } } };
|
|
3734
|
-
}, removeSubscriber = (key, subscriptionId) => (prev) => {
|
|
3735
|
-
const prevQuery = prev.queries[key];
|
|
3736
|
-
if (!prevQuery) return prev;
|
|
3737
|
-
const subscribers = prevQuery.subscribers.filter((id) => id !== subscriptionId);
|
|
3738
|
-
return subscribers.length ? { ...prev, queries: { ...prev.queries, [key]: { ...prevQuery, subscribers } } } : { ...prev, queries: omit(prev.queries, key) };
|
|
3739
|
-
}, cancelQuery = (key) => (prev) => {
|
|
3740
|
-
const prevQuery = prev.queries[key];
|
|
3741
|
-
return !prevQuery || prevQuery.subscribers.length ? prev : { ...prev, queries: omit(prev.queries, key) };
|
|
3742
|
-
}, initializeQuery = (key) => (prev) => prev.queries[key] ? prev : { ...prev, queries: { ...prev.queries, [key]: { subscribers: [] } } }, EMPTY_ARRAY = [], getQueryKey = (options) => JSON.stringify(options), parseQueryKey = (key) => JSON.parse(key);
|
|
3743
|
-
function normalizeOptionsWithPerspective(instance, options) {
|
|
3744
|
-
if (options.perspective !== void 0) return options;
|
|
3745
|
-
const instancePerspective = instance.config.perspective;
|
|
3746
|
-
return {
|
|
3747
|
-
...options,
|
|
3748
|
-
perspective: instancePerspective !== void 0 ? instancePerspective : QUERY_STORE_DEFAULT_PERSPECTIVE
|
|
3749
|
-
};
|
|
3750
|
-
}
|
|
3751
|
-
const queryStore = {
|
|
3752
|
-
name: "QueryStore",
|
|
3753
|
-
getInitialState: () => ({ queries: {} }),
|
|
3754
|
-
initialize(context) {
|
|
3755
|
-
const subscriptions = [
|
|
3756
|
-
listenForNewSubscribersAndFetch(context),
|
|
3757
|
-
listenToLiveClientAndSetLastLiveEventIds(context)
|
|
3758
|
-
];
|
|
3759
|
-
return () => {
|
|
3760
|
-
for (const subscription of subscriptions)
|
|
3761
|
-
subscription.unsubscribe();
|
|
3762
|
-
};
|
|
3763
|
-
}
|
|
3764
|
-
}, errorHandler = (state) => (error) => state.set("setError", { error }), listenForNewSubscribersAndFetch = ({ state, instance }) => state.observable.pipe(
|
|
3765
|
-
map((s) => new Set(Object.keys(s.queries))),
|
|
3766
|
-
distinctUntilChanged((curr, next) => curr.size !== next.size ? !1 : Array.from(next).every((i) => curr.has(i))),
|
|
3767
|
-
startWith$1(/* @__PURE__ */ new Set()),
|
|
3768
|
-
pairwise$1(),
|
|
3769
|
-
mergeMap$1(([curr, next]) => {
|
|
3770
|
-
const added = Array.from(next).filter((i) => !curr.has(i)), removed = Array.from(curr).filter((i) => !next.has(i));
|
|
3771
|
-
return [
|
|
3772
|
-
...added.map((key) => ({ key, added: !0 })),
|
|
3773
|
-
...removed.map((key) => ({ key, added: !1 }))
|
|
3774
|
-
];
|
|
3775
|
-
}),
|
|
3776
|
-
groupBy$1((i) => i.key),
|
|
3777
|
-
mergeMap$1(
|
|
3778
|
-
(group$) => group$.pipe(
|
|
3779
|
-
switchMap((e) => {
|
|
3780
|
-
if (!e.added) return EMPTY;
|
|
3781
|
-
const lastLiveEventId$ = state.observable.pipe(
|
|
3782
|
-
map((s) => s.queries[group$.key]?.lastLiveEventId),
|
|
3783
|
-
distinctUntilChanged()
|
|
3784
|
-
), {
|
|
3785
|
-
query,
|
|
3786
|
-
params,
|
|
3787
|
-
projectId,
|
|
3788
|
-
dataset,
|
|
3789
|
-
tag,
|
|
3790
|
-
source,
|
|
3791
|
-
perspective: perspectiveFromOptions,
|
|
3792
|
-
...restOptions
|
|
3793
|
-
} = parseQueryKey(group$.key), perspective$ = isReleasePerspective(perspectiveFromOptions) ? getPerspectiveState(instance, {
|
|
3794
|
-
perspective: perspectiveFromOptions
|
|
3795
|
-
}).observable.pipe(filter(Boolean)) : of(perspectiveFromOptions ?? QUERY_STORE_DEFAULT_PERSPECTIVE), client$ = getClientState(instance, {
|
|
3796
|
-
apiVersion: QUERY_STORE_API_VERSION,
|
|
3797
|
-
projectId,
|
|
3798
|
-
dataset,
|
|
3799
|
-
source
|
|
3800
|
-
}).observable;
|
|
3801
|
-
return combineLatest({
|
|
3802
|
-
lastLiveEventId: lastLiveEventId$,
|
|
3803
|
-
client: client$,
|
|
3804
|
-
perspective: perspective$
|
|
3805
|
-
}).pipe(
|
|
3806
|
-
switchMap(
|
|
3807
|
-
({ lastLiveEventId, client, perspective }) => client.observable.fetch(query, params, {
|
|
3808
|
-
...restOptions,
|
|
3809
|
-
perspective,
|
|
3810
|
-
filterResponse: !1,
|
|
3811
|
-
returnQuery: !1,
|
|
3812
|
-
lastLiveEventId,
|
|
3813
|
-
tag
|
|
3814
|
-
})
|
|
3815
|
-
)
|
|
3816
|
-
);
|
|
3817
|
-
}),
|
|
3818
|
-
catchError$1((error) => (state.set("setQueryError", setQueryError(group$.key, error)), EMPTY)),
|
|
3819
|
-
tap$1(({ result, syncTags }) => {
|
|
3820
|
-
state.set("setQueryData", setQueryData(group$.key, result, syncTags));
|
|
3821
|
-
})
|
|
3822
|
-
)
|
|
3823
|
-
)
|
|
3824
|
-
).subscribe({ error: errorHandler(state) }), listenToLiveClientAndSetLastLiveEventIds = ({
|
|
3825
|
-
state,
|
|
3826
|
-
instance,
|
|
3827
|
-
key: { source }
|
|
3828
|
-
}) => {
|
|
3829
|
-
const liveMessages$ = getClientState(instance, {
|
|
3830
|
-
apiVersion: QUERY_STORE_API_VERSION,
|
|
3831
|
-
// temporary guard here until we're ready for everything to be queried via global api
|
|
3832
|
-
...source && !isDatasetSource(source) ? { source } : {}
|
|
3833
|
-
}).observable.pipe(
|
|
3834
|
-
switchMap(
|
|
3835
|
-
(client) => defer(
|
|
3836
|
-
() => client.live.events({ includeDrafts: !!client.config().token, tag: "query-store" })
|
|
3837
|
-
).pipe(
|
|
3838
|
-
catchError$1((error) => {
|
|
3839
|
-
if (error instanceof CorsOriginError)
|
|
3840
|
-
return state.set("setError", { error }), EMPTY;
|
|
3841
|
-
throw error;
|
|
3842
|
-
})
|
|
3843
|
-
)
|
|
3844
|
-
),
|
|
3845
|
-
share(),
|
|
3846
|
-
filter((e) => e.type === "message")
|
|
3847
|
-
);
|
|
3848
|
-
return state.observable.pipe(
|
|
3849
|
-
mergeMap$1((s) => Object.entries(s.queries)),
|
|
3850
|
-
groupBy$1(([key]) => key),
|
|
3851
|
-
mergeMap$1((group$) => {
|
|
3852
|
-
const syncTags$ = group$.pipe(
|
|
3853
|
-
map(([, queryState]) => queryState),
|
|
3854
|
-
map((i) => i?.syncTags ?? EMPTY_ARRAY),
|
|
3855
|
-
distinctUntilChanged()
|
|
3856
|
-
);
|
|
3857
|
-
return combineLatest([liveMessages$, syncTags$]).pipe(
|
|
3858
|
-
filter(([message, syncTags]) => message.tags.some((tag) => syncTags.includes(tag))),
|
|
3859
|
-
tap$1(([message]) => {
|
|
3860
|
-
state.set("setLastLiveEventId", setLastLiveEventId(group$.key, message.id));
|
|
3861
|
-
})
|
|
3862
|
-
);
|
|
3863
|
-
})
|
|
3864
|
-
).subscribe({ error: errorHandler(state) });
|
|
3865
|
-
};
|
|
3866
|
-
function getQueryState(...args) {
|
|
3867
|
-
return _getQueryState(...args);
|
|
3868
|
-
}
|
|
3869
|
-
const _getQueryState = bindActionBySource(
|
|
3870
|
-
queryStore,
|
|
3871
|
-
createStateSourceAction({
|
|
3872
|
-
selector: ({ state, instance }, options) => {
|
|
3873
|
-
if (state.error) throw state.error;
|
|
3874
|
-
const key = getQueryKey(normalizeOptionsWithPerspective(instance, options)), queryState = state.queries[key];
|
|
3875
|
-
if (queryState?.error) throw queryState.error;
|
|
3876
|
-
return queryState?.result;
|
|
3877
|
-
},
|
|
3878
|
-
onSubscribe: ({ state, instance }, options) => {
|
|
3879
|
-
const subscriptionId = insecureRandomId(), key = getQueryKey(normalizeOptionsWithPerspective(instance, options));
|
|
3880
|
-
return state.set("addSubscriber", addSubscriber(key, subscriptionId)), () => {
|
|
3881
|
-
setTimeout(
|
|
3882
|
-
() => state.set("removeSubscriber", removeSubscriber(key, subscriptionId)),
|
|
3883
|
-
QUERY_STATE_CLEAR_DELAY
|
|
3884
|
-
);
|
|
3885
|
-
};
|
|
3886
|
-
}
|
|
3887
|
-
})
|
|
3888
|
-
);
|
|
3889
|
-
function resolveQuery(...args) {
|
|
3890
|
-
return _resolveQuery(...args);
|
|
3891
|
-
}
|
|
3892
|
-
const _resolveQuery = bindActionBySource(
|
|
3893
|
-
queryStore,
|
|
3894
|
-
({ state, instance }, { signal, ...options }) => {
|
|
3895
|
-
const normalized = normalizeOptionsWithPerspective(instance, options), { getCurrent } = getQueryState(instance, normalized), key = getQueryKey(normalized), aborted$ = signal ? new Observable((observer) => {
|
|
3896
|
-
const cleanup = () => {
|
|
3897
|
-
signal.removeEventListener("abort", listener);
|
|
3898
|
-
}, listener = () => {
|
|
3899
|
-
observer.error(new DOMException("The operation was aborted.", "AbortError")), observer.complete(), cleanup();
|
|
3900
|
-
};
|
|
3901
|
-
return signal.addEventListener("abort", listener), cleanup;
|
|
3902
|
-
}).pipe(
|
|
3903
|
-
catchError$1((error) => {
|
|
3904
|
-
throw error instanceof Error && error.name === "AbortError" && state.set("cancelQuery", cancelQuery(key)), error;
|
|
3905
|
-
})
|
|
3906
|
-
) : NEVER;
|
|
3907
|
-
state.set("initializeQuery", initializeQuery(key));
|
|
3908
|
-
const resolved$ = state.observable.pipe(
|
|
3909
|
-
map(getCurrent),
|
|
3910
|
-
first$1((i) => i !== void 0)
|
|
3911
|
-
);
|
|
3912
|
-
return firstValueFrom(race([resolved$, aborted$]));
|
|
3913
|
-
}
|
|
3914
|
-
);
|
|
3915
2750
|
function hashString(str) {
|
|
3916
2751
|
let hash = 0;
|
|
3917
2752
|
for (let i = 0; i < str.length; i++)
|
|
3918
2753
|
hash = (hash * 31 + str.charCodeAt(i)) % 2147483647;
|
|
3919
2754
|
return Math.abs(hash).toString(16).padStart(8, "0");
|
|
3920
2755
|
}
|
|
3921
|
-
const
|
|
3922
|
-
// Get all potential title fields
|
|
3923
|
-
"titleCandidates": {
|
|
3924
|
-
${TITLE_CANDIDATES.map((field) => `"${field}": ${field}`).join(`,
|
|
3925
|
-
`)}
|
|
3926
|
-
},
|
|
3927
|
-
// Get all potential subtitle fields
|
|
3928
|
-
"subtitleCandidates": {
|
|
3929
|
-
${SUBTITLE_CANDIDATES.map((field) => `"${field}": ${field}`).join(`,
|
|
3930
|
-
`)}
|
|
3931
|
-
},
|
|
3932
|
-
"media": coalesce(
|
|
3933
|
-
select(
|
|
3934
|
-
defined(asset) => {"type": "image-asset", "_ref": asset._ref},
|
|
3935
|
-
defined(image.asset) => {"type": "image-asset", "_ref": image.asset._ref},
|
|
3936
|
-
defined(mainImage.asset) => {"type": "image-asset", "_ref": mainImage.asset._ref},
|
|
3937
|
-
null
|
|
3938
|
-
)
|
|
3939
|
-
),
|
|
3940
|
-
_type,
|
|
3941
|
-
_id,
|
|
3942
|
-
_updatedAt
|
|
3943
|
-
}`, PREVIEW_TAG = "preview", PREVIEW_PERSPECTIVE = "raw", STABLE_EMPTY_PREVIEW = { data: null, isPending: !1 }, STABLE_ERROR_PREVIEW = {
|
|
3944
|
-
data: {
|
|
3945
|
-
title: "Preview Error",
|
|
3946
|
-
...!!getEnv("DEV") && { subtitle: "Check the console for more details" }
|
|
3947
|
-
},
|
|
3948
|
-
isPending: !1
|
|
3949
|
-
};
|
|
3950
|
-
function assetIdToUrl(assetId, projectId, dataset) {
|
|
3951
|
-
const pattern = /^image-(?<assetName>[A-Za-z0-9]+)-(?<dimensions>\d+x\d+)-(?<format>[a-z]+)$/, match = assetId.match(pattern);
|
|
3952
|
-
if (!match?.groups)
|
|
3953
|
-
throw new Error(
|
|
3954
|
-
`Invalid asset ID \`${assetId}\`. Expected: image-{assetName}-{width}x{height}-{format}`
|
|
3955
|
-
);
|
|
3956
|
-
const { assetName, dimensions, format } = match.groups;
|
|
3957
|
-
return `https://cdn.sanity.io/images/${projectId}/${dataset}/${assetName}-${dimensions}.${format}`;
|
|
3958
|
-
}
|
|
3959
|
-
function hasImageRef(value) {
|
|
3960
|
-
return isObject(value) && "_ref" in value && typeof value._ref == "string";
|
|
3961
|
-
}
|
|
3962
|
-
function normalizeMedia(media, projectId, dataset) {
|
|
3963
|
-
return !media || !hasImageRef(media) ? null : {
|
|
3964
|
-
type: "image-asset",
|
|
3965
|
-
_ref: media._ref,
|
|
3966
|
-
url: assetIdToUrl(media._ref, projectId, dataset)
|
|
3967
|
-
};
|
|
3968
|
-
}
|
|
3969
|
-
function findFirstDefined(fieldsToSearch, candidates, exclude) {
|
|
3970
|
-
if (candidates)
|
|
3971
|
-
for (const field of fieldsToSearch) {
|
|
3972
|
-
const value = candidates[field];
|
|
3973
|
-
if (typeof value == "string" && value.trim() !== "" && value !== exclude)
|
|
3974
|
-
return value;
|
|
3975
|
-
}
|
|
3976
|
-
}
|
|
3977
|
-
function processPreviewQuery({
|
|
3978
|
-
projectId,
|
|
3979
|
-
dataset,
|
|
3980
|
-
ids,
|
|
3981
|
-
results
|
|
3982
|
-
}) {
|
|
3983
|
-
const resultMap = results.reduce((acc, next) => (acc[next._id] = next, acc), {});
|
|
3984
|
-
return Object.fromEntries(
|
|
3985
|
-
Array.from(ids).map((id) => {
|
|
3986
|
-
const publishedId = getPublishedId(id), draftId = getDraftId(id), draftResult = resultMap[draftId], publishedResult = resultMap[publishedId];
|
|
3987
|
-
if (!draftResult && !publishedResult) return [id, STABLE_EMPTY_PREVIEW];
|
|
3988
|
-
try {
|
|
3989
|
-
const result = draftResult || publishedResult;
|
|
3990
|
-
if (!result) return [id, STABLE_EMPTY_PREVIEW];
|
|
3991
|
-
const title = findFirstDefined(TITLE_CANDIDATES, result.titleCandidates), subtitle = findFirstDefined(SUBTITLE_CANDIDATES, result.subtitleCandidates, title), preview = {
|
|
3992
|
-
title: String(title || `${result._type}: ${result._id}`),
|
|
3993
|
-
subtitle: subtitle || void 0,
|
|
3994
|
-
media: normalizeMedia(result.media, projectId, dataset)
|
|
3995
|
-
}, _status = {
|
|
3996
|
-
...draftResult?._updatedAt && { lastEditedDraftAt: draftResult._updatedAt },
|
|
3997
|
-
...publishedResult?._updatedAt && { lastEditedPublishedAt: publishedResult._updatedAt }
|
|
3998
|
-
};
|
|
3999
|
-
return [id, { data: { ...preview, _status }, isPending: !1 }];
|
|
4000
|
-
} catch (e) {
|
|
4001
|
-
return console.warn(e), [id, STABLE_ERROR_PREVIEW];
|
|
4002
|
-
}
|
|
4003
|
-
})
|
|
4004
|
-
);
|
|
4005
|
-
}
|
|
4006
|
-
function createPreviewQuery(documentIds) {
|
|
4007
|
-
const allIds = Array.from(documentIds).flatMap((id) => [getPublishedId(id), getDraftId(id)]), queryHash = hashString(PREVIEW_PROJECTION);
|
|
4008
|
-
return {
|
|
4009
|
-
query: `*[_id in $__ids_${queryHash}]${PREVIEW_PROJECTION}`,
|
|
4010
|
-
params: {
|
|
4011
|
-
[`__ids_${queryHash}`]: allIds
|
|
4012
|
-
}
|
|
4013
|
-
};
|
|
4014
|
-
}
|
|
4015
|
-
const BATCH_DEBOUNCE_TIME$1 = 50, isSetEqual$1 = (a, b) => a.size === b.size && Array.from(a).every((i) => b.has(i)), subscribeToStateAndFetchBatches$1 = ({
|
|
4016
|
-
state,
|
|
4017
|
-
instance,
|
|
4018
|
-
key: { projectId, dataset }
|
|
4019
|
-
}) => state.observable.pipe(
|
|
4020
|
-
map(({ subscriptions }) => new Set(Object.keys(subscriptions))),
|
|
4021
|
-
distinctUntilChanged(isSetEqual$1),
|
|
4022
|
-
debounceTime(BATCH_DEBOUNCE_TIME$1),
|
|
4023
|
-
startWith$1(/* @__PURE__ */ new Set()),
|
|
4024
|
-
pairwise$1(),
|
|
4025
|
-
tap$1(([prevIds, currIds]) => {
|
|
4026
|
-
const newIds = [...currIds].filter((element) => !prevIds.has(element));
|
|
4027
|
-
state.set("updatingPending", (prev) => {
|
|
4028
|
-
const pendingValues = newIds.reduce((acc, id) => {
|
|
4029
|
-
const prevValue = prev.values[id], value = prevValue?.data ? prevValue.data : null;
|
|
4030
|
-
return acc[id] = { data: value, isPending: !0 }, acc;
|
|
4031
|
-
}, {});
|
|
4032
|
-
return { values: { ...prev.values, ...pendingValues } };
|
|
4033
|
-
});
|
|
4034
|
-
}),
|
|
4035
|
-
map(([, ids]) => ids),
|
|
4036
|
-
distinctUntilChanged(isSetEqual$1)
|
|
4037
|
-
).pipe(
|
|
4038
|
-
switchMap((ids) => {
|
|
4039
|
-
if (!ids.size) return EMPTY;
|
|
4040
|
-
const { query, params } = createPreviewQuery(ids), controller = new AbortController();
|
|
4041
|
-
return new Observable((observer) => {
|
|
4042
|
-
const { getCurrent, observable } = getQueryState(instance, {
|
|
4043
|
-
query,
|
|
4044
|
-
params,
|
|
4045
|
-
tag: PREVIEW_TAG,
|
|
4046
|
-
perspective: PREVIEW_PERSPECTIVE,
|
|
4047
|
-
projectId,
|
|
4048
|
-
dataset
|
|
4049
|
-
}), subscription = defer(() => getCurrent() === void 0 ? from(
|
|
4050
|
-
resolveQuery(instance, {
|
|
4051
|
-
query,
|
|
4052
|
-
params,
|
|
4053
|
-
tag: PREVIEW_TAG,
|
|
4054
|
-
perspective: PREVIEW_PERSPECTIVE,
|
|
4055
|
-
signal: controller.signal,
|
|
4056
|
-
projectId,
|
|
4057
|
-
dataset
|
|
4058
|
-
})
|
|
4059
|
-
).pipe(switchMap(() => observable)) : observable).pipe(filter((result) => result !== void 0)).subscribe(observer);
|
|
4060
|
-
return () => {
|
|
4061
|
-
controller.signal.aborted || controller.abort(), subscription.unsubscribe();
|
|
4062
|
-
};
|
|
4063
|
-
}).pipe(map((data) => ({ data, ids })));
|
|
4064
|
-
}),
|
|
4065
|
-
map(({ ids, data }) => ({
|
|
4066
|
-
values: processPreviewQuery({
|
|
4067
|
-
projectId,
|
|
4068
|
-
dataset,
|
|
4069
|
-
ids,
|
|
4070
|
-
results: data
|
|
4071
|
-
})
|
|
4072
|
-
}))
|
|
4073
|
-
).subscribe({
|
|
4074
|
-
next: ({ values }) => {
|
|
4075
|
-
state.set("updateResult", (prev) => ({ values: { ...prev.values, ...values } }));
|
|
4076
|
-
}
|
|
4077
|
-
}), previewStore = {
|
|
4078
|
-
name: "Preview",
|
|
4079
|
-
getInitialState() {
|
|
4080
|
-
return {
|
|
4081
|
-
subscriptions: {},
|
|
4082
|
-
values: {}
|
|
4083
|
-
};
|
|
4084
|
-
},
|
|
4085
|
-
initialize: (context) => {
|
|
4086
|
-
const subscription = subscribeToStateAndFetchBatches$1(context);
|
|
4087
|
-
return () => subscription.unsubscribe;
|
|
4088
|
-
}
|
|
4089
|
-
};
|
|
4090
|
-
function getPreviewState(...args) {
|
|
4091
|
-
return _getPreviewState(...args);
|
|
4092
|
-
}
|
|
4093
|
-
const _getPreviewState = bindActionByDataset(
|
|
4094
|
-
previewStore,
|
|
4095
|
-
createStateSourceAction({
|
|
4096
|
-
selector: ({ state }, docHandle) => state.values[docHandle.documentId] ?? STABLE_EMPTY_PREVIEW,
|
|
4097
|
-
onSubscribe: ({ state }, docHandle) => {
|
|
4098
|
-
const subscriptionId = insecureRandomId(), documentId = getPublishedId(docHandle.documentId);
|
|
4099
|
-
return state.set("addSubscription", (prev) => ({
|
|
4100
|
-
subscriptions: {
|
|
4101
|
-
...prev.subscriptions,
|
|
4102
|
-
[documentId]: {
|
|
4103
|
-
...prev.subscriptions[documentId],
|
|
4104
|
-
[subscriptionId]: !0
|
|
4105
|
-
}
|
|
4106
|
-
}
|
|
4107
|
-
})), () => {
|
|
4108
|
-
state.set("removeSubscription", (prev) => {
|
|
4109
|
-
const documentSubscriptions = omit(prev.subscriptions[documentId], subscriptionId), hasSubscribers = !!Object.keys(documentSubscriptions).length, prevValue = prev.values[documentId], previewValue = prevValue?.data ? prevValue.data : null;
|
|
4110
|
-
return {
|
|
4111
|
-
subscriptions: hasSubscribers ? { ...prev.subscriptions, [documentId]: documentSubscriptions } : omit(prev.subscriptions, documentId),
|
|
4112
|
-
values: hasSubscribers ? prev.values : { ...prev.values, [documentId]: { data: previewValue, isPending: !1 } }
|
|
4113
|
-
};
|
|
4114
|
-
});
|
|
4115
|
-
};
|
|
4116
|
-
}
|
|
4117
|
-
})
|
|
4118
|
-
), resolvePreview = bindActionByDataset(
|
|
4119
|
-
previewStore,
|
|
4120
|
-
({ instance }, docHandle) => firstValueFrom(getPreviewState(instance, docHandle).observable.pipe(filter((i) => !!i.data)))
|
|
4121
|
-
), PROJECTION_TAG = "projection", PROJECTION_STATE_CLEAR_DELAY = 1e3, STABLE_EMPTY_PROJECTION = {
|
|
2756
|
+
const PROJECTION_TAG = "projection", PROJECTION_STATE_CLEAR_DELAY = 1e3, STABLE_EMPTY_PROJECTION = {
|
|
4122
2757
|
data: null,
|
|
4123
2758
|
isPending: !1
|
|
4124
2759
|
};
|
|
@@ -4155,7 +2790,7 @@ function processProjectionQuery({
|
|
|
4155
2790
|
}) {
|
|
4156
2791
|
const groupedResults = {};
|
|
4157
2792
|
for (const result of results) {
|
|
4158
|
-
const originalId = getPublishedId(result._id), hash = result.__projectionHash;
|
|
2793
|
+
const originalId = getPublishedId(DocumentId(result._id)), hash = result.__projectionHash;
|
|
4159
2794
|
ids.has(originalId) && (groupedResults[originalId] || (groupedResults[originalId] = {}), groupedResults[originalId][hash] || (groupedResults[originalId][hash] = void 0), groupedResults[originalId][hash] = result);
|
|
4160
2795
|
}
|
|
4161
2796
|
const finalValues = {};
|
|
@@ -4181,7 +2816,7 @@ function processProjectionQuery({
|
|
|
4181
2816
|
function buildStatusQueryIds(documentIds, perspective) {
|
|
4182
2817
|
const ids = [], releaseName = isReleasePerspective(perspective) ? perspective.releaseName : null;
|
|
4183
2818
|
for (const id of documentIds) {
|
|
4184
|
-
const publishedId = getPublishedId
|
|
2819
|
+
const publishedId = getPublishedId(DocumentId(id)), draftId = getDraftId(publishedId);
|
|
4185
2820
|
ids.push(draftId, publishedId), releaseName && ids.push(getVersionId(publishedId, releaseName));
|
|
4186
2821
|
}
|
|
4187
2822
|
return ids;
|
|
@@ -4189,7 +2824,7 @@ function buildStatusQueryIds(documentIds, perspective) {
|
|
|
4189
2824
|
function processStatusQueryResults(results) {
|
|
4190
2825
|
const documentStatuses = {};
|
|
4191
2826
|
for (const result of results) {
|
|
4192
|
-
const id = DocumentId(result._id), updatedAt = result._updatedAt, publishedId = getPublishedId
|
|
2827
|
+
const id = DocumentId(result._id), updatedAt = result._updatedAt, publishedId = getPublishedId(id), statusData = documentStatuses[publishedId] ?? {};
|
|
4193
2828
|
isDraftId(id) ? statusData.lastEditedDraftAt = updatedAt : isVersionId(id) ? statusData.lastEditedVersionAt = updatedAt : isPublishedId(id) && (statusData.lastEditedPublishedAt = updatedAt), documentStatuses[publishedId] = statusData;
|
|
4194
2829
|
}
|
|
4195
2830
|
return documentStatuses;
|
|
@@ -4197,13 +2832,13 @@ function processStatusQueryResults(results) {
|
|
|
4197
2832
|
const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Array.from(a).every((i) => b.has(i)), subscribeToStateAndFetchBatches = ({
|
|
4198
2833
|
state,
|
|
4199
2834
|
instance,
|
|
4200
|
-
key: {
|
|
2835
|
+
key: { resource, perspective }
|
|
4201
2836
|
}) => {
|
|
4202
2837
|
const documentProjections$ = state.observable.pipe(
|
|
4203
|
-
map((s) => s.documentProjections),
|
|
4204
|
-
distinctUntilChanged(
|
|
2838
|
+
map$1((s) => s.documentProjections),
|
|
2839
|
+
distinctUntilChanged(isDeepEqual)
|
|
4205
2840
|
), activeDocumentIds$ = state.observable.pipe(
|
|
4206
|
-
map(({ subscriptions }) => new Set(Object.keys(subscriptions))),
|
|
2841
|
+
map$1(({ subscriptions }) => new Set(Object.keys(subscriptions).map((id) => DocumentId(id)))),
|
|
4207
2842
|
distinctUntilChanged(isSetEqual)
|
|
4208
2843
|
), pendingUpdateSubscription = activeDocumentIds$.pipe(
|
|
4209
2844
|
debounceTime(BATCH_DEBOUNCE_TIME),
|
|
@@ -4231,7 +2866,7 @@ const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Arra
|
|
|
4231
2866
|
})
|
|
4232
2867
|
).subscribe(), queryExecutionSubscription = combineLatest([activeDocumentIds$, documentProjections$]).pipe(
|
|
4233
2868
|
debounceTime(BATCH_DEBOUNCE_TIME),
|
|
4234
|
-
distinctUntilChanged(
|
|
2869
|
+
distinctUntilChanged(isDeepEqual)
|
|
4235
2870
|
).pipe(
|
|
4236
2871
|
switchMap(([ids, documentProjections]) => {
|
|
4237
2872
|
if (!ids.size) return EMPTY;
|
|
@@ -4242,7 +2877,7 @@ const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Arra
|
|
|
4242
2877
|
tag: PROJECTION_TAG,
|
|
4243
2878
|
perspective,
|
|
4244
2879
|
// temporary guard here until we're ready for everything to be queried via global API
|
|
4245
|
-
...
|
|
2880
|
+
...resource && !isDatasetResource(resource) ? { resource } : {}
|
|
4246
2881
|
}), subscription = defer(() => getCurrent() === void 0 ? from(
|
|
4247
2882
|
resolveQuery(instance, {
|
|
4248
2883
|
query,
|
|
@@ -4251,9 +2886,9 @@ const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Arra
|
|
|
4251
2886
|
signal: controller.signal,
|
|
4252
2887
|
perspective,
|
|
4253
2888
|
// temporary guard here until we're ready for everything to be queried via global API in v3
|
|
4254
|
-
...
|
|
2889
|
+
...resource && !isDatasetResource(resource) ? { resource } : {}
|
|
4255
2890
|
})
|
|
4256
|
-
).pipe(switchMap(() => observable)) : observable).pipe(filter((result) => result !== void 0)).subscribe(observer);
|
|
2891
|
+
).pipe(switchMap(() => observable)) : observable).pipe(filter$1((result) => result !== void 0)).subscribe(observer);
|
|
4257
2892
|
return () => {
|
|
4258
2893
|
controller.signal.aborted || controller.abort(), subscription.unsubscribe();
|
|
4259
2894
|
};
|
|
@@ -4264,7 +2899,7 @@ const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Arra
|
|
|
4264
2899
|
tag: PROJECTION_TAG,
|
|
4265
2900
|
perspective: "raw",
|
|
4266
2901
|
// temporary guard here until we're ready for everything to be queried via global API
|
|
4267
|
-
...
|
|
2902
|
+
...resource && !isDatasetResource(resource) ? { resource } : {}
|
|
4268
2903
|
}), subscription = defer(() => getCurrent() === void 0 ? from(
|
|
4269
2904
|
resolveQuery(instance, {
|
|
4270
2905
|
query: statusQuery,
|
|
@@ -4273,25 +2908,25 @@ const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Arra
|
|
|
4273
2908
|
signal: controller.signal,
|
|
4274
2909
|
perspective: "raw",
|
|
4275
2910
|
// temporary guard here until we're ready for everything to be queried via global API
|
|
4276
|
-
...
|
|
2911
|
+
...resource && !isDatasetResource(resource) ? { resource } : {}
|
|
4277
2912
|
})
|
|
4278
|
-
).pipe(switchMap(() => observable)) : observable).pipe(filter((result) => result !== void 0)).subscribe(observer);
|
|
2913
|
+
).pipe(switchMap(() => observable)) : observable).pipe(filter$1((result) => result !== void 0)).subscribe(observer);
|
|
4279
2914
|
return () => {
|
|
4280
2915
|
subscription.unsubscribe();
|
|
4281
2916
|
};
|
|
4282
2917
|
});
|
|
4283
2918
|
return combineLatest([projectionQuery$, statusQuery$]).pipe(
|
|
4284
|
-
filter(
|
|
2919
|
+
filter$1(
|
|
4285
2920
|
(pair) => pair[0] !== void 0 && pair[1] !== void 0
|
|
4286
2921
|
),
|
|
4287
|
-
map(([projection, status]) => ({
|
|
2922
|
+
map$1(([projection, status]) => ({
|
|
4288
2923
|
data: projection,
|
|
4289
2924
|
ids,
|
|
4290
2925
|
statusResults: status
|
|
4291
2926
|
}))
|
|
4292
2927
|
);
|
|
4293
2928
|
}),
|
|
4294
|
-
map(({ ids, data, statusResults }) => {
|
|
2929
|
+
map$1(({ ids, data, statusResults }) => {
|
|
4295
2930
|
const documentStatuses = processStatusQueryResults(statusResults);
|
|
4296
2931
|
state.set("updateStatuses", (prev) => ({
|
|
4297
2932
|
documentStatuses: {
|
|
@@ -4325,7 +2960,7 @@ const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Arra
|
|
|
4325
2960
|
return new Subscription(() => {
|
|
4326
2961
|
pendingUpdateSubscription.unsubscribe(), queryExecutionSubscription.unsubscribe();
|
|
4327
2962
|
});
|
|
4328
|
-
}, projectionStore = {
|
|
2963
|
+
}, projectionStore = defineStore({
|
|
4329
2964
|
name: "Projection",
|
|
4330
2965
|
getInitialState() {
|
|
4331
2966
|
return {
|
|
@@ -4339,19 +2974,19 @@ const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Arra
|
|
|
4339
2974
|
const batchSubscription = subscribeToStateAndFetchBatches(context);
|
|
4340
2975
|
return () => batchSubscription.unsubscribe();
|
|
4341
2976
|
}
|
|
4342
|
-
};
|
|
2977
|
+
});
|
|
4343
2978
|
function getProjectionState(...args) {
|
|
4344
2979
|
return _getProjectionState(...args);
|
|
4345
2980
|
}
|
|
4346
|
-
const _getProjectionState =
|
|
2981
|
+
const _getProjectionState = bindActionByResourceAndPerspective(
|
|
4347
2982
|
projectionStore,
|
|
4348
2983
|
createStateSourceAction({
|
|
4349
2984
|
selector: ({ state }, options) => {
|
|
4350
|
-
const documentId = getPublishedId
|
|
2985
|
+
const documentId = getPublishedId(DocumentId(options.documentId)), projectionHash = hashString(options.projection);
|
|
4351
2986
|
return state.values[documentId]?.[projectionHash] ?? STABLE_EMPTY_PROJECTION;
|
|
4352
2987
|
},
|
|
4353
2988
|
onSubscribe: ({ state }, options) => {
|
|
4354
|
-
const { projection, ...docHandle } = options, subscriptionId = insecureRandomId(), documentId = getPublishedId
|
|
2989
|
+
const { projection, ...docHandle } = options, subscriptionId = insecureRandomId(), documentId = getPublishedId(DocumentId(docHandle.documentId)), validProjection = validateProjection(projection), projectionHash = hashString(validProjection);
|
|
4355
2990
|
return state.set("addSubscription", (prev) => ({
|
|
4356
2991
|
documentProjections: {
|
|
4357
2992
|
...prev.documentProjections,
|
|
@@ -4371,9 +3006,9 @@ const _getProjectionState = bindActionBySourceAndPerspective(
|
|
|
4371
3006
|
}
|
|
4372
3007
|
}
|
|
4373
3008
|
})), () => {
|
|
4374
|
-
|
|
3009
|
+
setCleanupTimeout(() => {
|
|
4375
3010
|
state.set("removeSubscription", (prev) => {
|
|
4376
|
-
const documentSubscriptionsForHash =
|
|
3011
|
+
const documentSubscriptionsForHash = omitProperty(
|
|
4377
3012
|
prev.subscriptions[documentId]?.[projectionHash],
|
|
4378
3013
|
subscriptionId
|
|
4379
3014
|
), hasSubscribersForProjection = !!Object.keys(documentSubscriptionsForHash).length, nextSubscriptions = { ...prev.subscriptions }, nextDocumentProjections = { ...prev.documentProjections }, nextValues = { ...prev.values };
|
|
@@ -4400,17 +3035,46 @@ const _getProjectionState = bindActionBySourceAndPerspective(
|
|
|
4400
3035
|
}
|
|
4401
3036
|
})
|
|
4402
3037
|
);
|
|
3038
|
+
function getPreviewState(instance, options) {
|
|
3039
|
+
const projectionState = getProjectionState(instance, {
|
|
3040
|
+
...options,
|
|
3041
|
+
projection: PREVIEW_PROJECTION
|
|
3042
|
+
}), transformResult = (current) => !current || current.data === null ? { data: null, isPending: current?.isPending ?? !1 } : {
|
|
3043
|
+
data: transformProjectionToPreview(instance, current.data, options.resource),
|
|
3044
|
+
isPending: current.isPending
|
|
3045
|
+
};
|
|
3046
|
+
return {
|
|
3047
|
+
getCurrent: () => transformResult(projectionState.getCurrent()),
|
|
3048
|
+
subscribe: (callback) => projectionState.subscribe(callback),
|
|
3049
|
+
observable: projectionState.observable.pipe(map$1(transformResult))
|
|
3050
|
+
};
|
|
3051
|
+
}
|
|
4403
3052
|
function resolveProjection(...args) {
|
|
4404
3053
|
return _resolveProjection(...args);
|
|
4405
3054
|
}
|
|
4406
|
-
const _resolveProjection =
|
|
3055
|
+
const _resolveProjection = bindActionByResourceAndPerspective(
|
|
4407
3056
|
projectionStore,
|
|
4408
3057
|
({ instance }, options) => firstValueFrom(
|
|
4409
3058
|
getProjectionState(instance, options).observable.pipe(
|
|
4410
|
-
filter((state) => !!state?.data)
|
|
3059
|
+
filter$1((state) => !!state?.data)
|
|
4411
3060
|
)
|
|
4412
3061
|
)
|
|
4413
|
-
)
|
|
3062
|
+
);
|
|
3063
|
+
async function resolvePreview(instance, options) {
|
|
3064
|
+
const projectionResult = await resolveProjection(instance, {
|
|
3065
|
+
...options,
|
|
3066
|
+
projection: PREVIEW_PROJECTION
|
|
3067
|
+
});
|
|
3068
|
+
return projectionResult.data ? {
|
|
3069
|
+
data: transformProjectionToPreview(
|
|
3070
|
+
instance,
|
|
3071
|
+
projectionResult.data,
|
|
3072
|
+
options.resource
|
|
3073
|
+
),
|
|
3074
|
+
isPending: projectionResult.isPending
|
|
3075
|
+
} : { data: null, isPending: projectionResult.isPending };
|
|
3076
|
+
}
|
|
3077
|
+
const API_VERSION = "v2025-02-19", projects = createFetcherStore({
|
|
4414
3078
|
name: "Projects",
|
|
4415
3079
|
getKey: (_instance, options) => {
|
|
4416
3080
|
const orgKey = options?.organizationId ? `:org:${options.organizationId}` : "", membersKey = options?.includeMembers === !1 ? ":no-members" : "";
|
|
@@ -4430,29 +3094,7 @@ const _resolveProjection = bindActionBySourceAndPerspective(
|
|
|
4430
3094
|
});
|
|
4431
3095
|
})
|
|
4432
3096
|
)
|
|
4433
|
-
}), getProjectsState = projects.getState, resolveProjects = projects.resolveState
|
|
4434
|
-
function isNegationToken(token) {
|
|
4435
|
-
return typeof token < "u" && token.trim().startsWith("-");
|
|
4436
|
-
}
|
|
4437
|
-
function isPrefixToken(token) {
|
|
4438
|
-
return typeof token < "u" && token.trim().endsWith("*");
|
|
4439
|
-
}
|
|
4440
|
-
function isExactMatchToken(token) {
|
|
4441
|
-
return !!token && token.length >= 2 && token.startsWith('"') && token.endsWith('"');
|
|
4442
|
-
}
|
|
4443
|
-
function createGroqSearchFilter(query) {
|
|
4444
|
-
const trimmedQuery = query.trim();
|
|
4445
|
-
if (!trimmedQuery)
|
|
4446
|
-
return "";
|
|
4447
|
-
const tokens = trimmedQuery.match(TOKEN_REGEX) ?? [], reversedIndex = [...tokens].reverse().findIndex(
|
|
4448
|
-
(token) => !isNegationToken(token) && !isExactMatchToken(token)
|
|
4449
|
-
), finalIncrementalTokenIndex = reversedIndex === -1 ? -1 : tokens.length - 1 - reversedIndex, finalIncrementalToken = tokens[finalIncrementalTokenIndex], processedTokens = [...tokens];
|
|
4450
|
-
return finalIncrementalToken !== void 0 && !isPrefixToken(finalIncrementalToken) && processedTokens.splice(
|
|
4451
|
-
finalIncrementalTokenIndex,
|
|
4452
|
-
1,
|
|
4453
|
-
`${finalIncrementalToken}*`
|
|
4454
|
-
), `[@] match text::query("${processedTokens.join(" ").replace(/"/g, '\\"')}")`;
|
|
4455
|
-
}
|
|
3097
|
+
}), getProjectsState = projects.getState, resolveProjects = projects.resolveState;
|
|
4456
3098
|
function defineIntent(intent) {
|
|
4457
3099
|
if (!intent.id)
|
|
4458
3100
|
throw new Error("Intent must have an id");
|
|
@@ -4511,11 +3153,16 @@ function getCorsErrorProjectId(error) {
|
|
|
4511
3153
|
const projMatch = (error.message || "").match(/manage\/project\/([^/?#]+)/);
|
|
4512
3154
|
return projMatch ? projMatch[1] : null;
|
|
4513
3155
|
}
|
|
4514
|
-
|
|
4515
|
-
|
|
3156
|
+
function isImportError(error) {
|
|
3157
|
+
if (!(error instanceof Error)) return !1;
|
|
3158
|
+
if (error.name === "ChunkLoadError") return !0;
|
|
3159
|
+
const message = error.message || "";
|
|
3160
|
+
return /Loading chunk [\w-]+ failed/i.test(message) || /Failed to fetch dynamically imported module/i.test(message) || /error loading dynamically imported module/i.test(message) || /Import(?:ing)? a module script failed/i.test(message) || /Unable to preload CSS/i.test(message);
|
|
3161
|
+
}
|
|
4516
3162
|
export {
|
|
4517
3163
|
AuthStateType,
|
|
4518
3164
|
CORE_SDK_VERSION,
|
|
3165
|
+
PREVIEW_PROJECTION,
|
|
4519
3166
|
agentGenerate,
|
|
4520
3167
|
agentPatch,
|
|
4521
3168
|
agentPrompt,
|
|
@@ -4571,8 +3218,12 @@ export {
|
|
|
4571
3218
|
getUsersKey,
|
|
4572
3219
|
getUsersState,
|
|
4573
3220
|
handleAuthCallback,
|
|
3221
|
+
isCanvasResource,
|
|
4574
3222
|
isCanvasSource,
|
|
3223
|
+
isDatasetResource,
|
|
4575
3224
|
isDatasetSource,
|
|
3225
|
+
isImportError,
|
|
3226
|
+
isMediaLibraryResource,
|
|
4576
3227
|
isMediaLibrarySource,
|
|
4577
3228
|
isProjectUserNotFoundClientError,
|
|
4578
3229
|
isStudioConfig,
|
|
@@ -4601,6 +3252,7 @@ export {
|
|
|
4601
3252
|
slicePath2 as slicePath,
|
|
4602
3253
|
stringifyPath2 as stringifyPath,
|
|
4603
3254
|
subscribeDocumentEvents,
|
|
3255
|
+
transformProjectionToPreview,
|
|
4604
3256
|
unpublishDocument
|
|
4605
3257
|
};
|
|
4606
3258
|
//# sourceMappingURL=index.js.map
|