@sanity/sdk 2.8.0 → 2.9.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 +2396 -0
- package/dist/_chunks-es/_internal.js +129 -0
- package/dist/_chunks-es/_internal.js.map +1 -0
- package/dist/_chunks-es/createGroqSearchFilter.js +1460 -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 +383 -1777
- package/dist/index.js.map +1 -1
- package/package.json +11 -4
- package/src/_exports/_internal.ts +14 -0
- package/src/_exports/index.ts +10 -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 +14 -0
- package/src/client/clientStore.ts +2 -1
- package/src/comlink/node/getNodeState.ts +2 -1
- package/src/config/sanityConfig.ts +6 -0
- 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 +536 -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 +104 -76
- package/src/document/reducers.test.ts +117 -29
- package/src/document/reducers.ts +43 -36
- 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.ts +6 -1
- 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 +29 -10
- package/src/preview/{previewStore.ts → types.ts} +8 -17
- package/src/projection/getProjectionState.test.ts +16 -16
- package/src/projection/getProjectionState.ts +2 -1
- package/src/projection/projectionQuery.ts +2 -3
- package/src/projection/types.ts +1 -1
- package/src/query/queryStore.ts +2 -1
- 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/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/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 +2 -1
- 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/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,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
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, insecureRandomId, getClientState, bindActionGlobally, defineStore, createStateSourceAction, setCleanupTimeout, authStore, getDefaultLocation, AuthStateType, getCleanedUrl, getTokenFromLocation, createLoggedInAuthState, getAuthCode, REQUEST_TAG_PREFIX, DEFAULT_API_VERSION, configureLogging as configureLogging$1, isReleasePerspective, isDatasetSource, bindActionBySource, isMediaLibrarySource, isCanvasSource, 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, bindActionByDataset, getTokenState, getQueryState, resolveQuery, bindActionBySourceAndPerspective, transformProjectionToPreview, PREVIEW_PROJECTION } from "./_chunks-es/createGroqSearchFilter.js";
|
|
3
|
+
import { createGroqSearchFilter, getActiveReleasesState, getAuthState, getClientErrorApiBody, getClientErrorApiDescription, getClientErrorApiType, getCurrentUserState, getIsInDashboardState, getLoginUrlState, getPerspectiveState, getQueryKey, isProjectUserNotFoundClientError, isStudioConfig, parseQueryKey, setAuthToken } from "./_chunks-es/createGroqSearchFilter.js";
|
|
4
|
+
import { pick, omit, isEqual } from "lodash-es";
|
|
5
|
+
import { first, switchMap as switchMap$1, groupBy, mergeMap, startWith, pairwise, filter, map, delay, tap, catchError, scan, share as share$1 } from "rxjs/operators";
|
|
7
6
|
import { createController, createNode } from "@sanity/comlink";
|
|
8
7
|
import { createSelector } from "reselect";
|
|
9
8
|
import { SanityEncoder } from "@sanity/mutate";
|
|
10
|
-
import { getPublishedId
|
|
9
|
+
import { getVersionId, getPublishedId, DocumentId, getDraftId, isDraftId, isVersionId, isPublishedId } from "@sanity/id-utils";
|
|
11
10
|
import { jsonMatch, stringifyPath, slicePath, getIndexForKey } from "@sanity/json-match";
|
|
12
11
|
import { getIndexForKey as getIndexForKey2, getPathDepth, joinPaths, jsonMatch as jsonMatch2, slicePath as slicePath2, stringifyPath as stringifyPath2 } from "@sanity/json-match";
|
|
13
12
|
import { evaluateSync, parse } from "groq-js";
|
|
@@ -17,142 +16,8 @@ import { isKeySegment, isKeyedObject } from "@sanity/types";
|
|
|
17
16
|
import { createDocumentLoaderFromClient } from "@sanity/mutate/_unstable_store";
|
|
18
17
|
import { SDK_CHANNEL_NAME, SDK_NODE_NAME } from "@sanity/message-protocol";
|
|
19
18
|
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
|
-
}
|
|
19
|
+
import { CorsOriginError } from "@sanity/client";
|
|
20
|
+
import { CORE_SDK_VERSION } from "./_chunks-es/version.js";
|
|
156
21
|
function createSanityInstance(config = {}) {
|
|
157
22
|
const instanceId = crypto.randomUUID(), disposeListeners = /* @__PURE__ */ new Map(), disposed = { current: !1 }, instanceContext = {
|
|
158
23
|
instanceId,
|
|
@@ -227,870 +92,38 @@ function createSanityInstance(config = {}) {
|
|
|
227
92
|
};
|
|
228
93
|
return instance;
|
|
229
94
|
}
|
|
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";
|
|
95
|
+
const API_VERSION$5 = "vX";
|
|
1063
96
|
function agentGenerate(instance, options) {
|
|
1064
97
|
return getClientState(instance, {
|
|
1065
|
-
apiVersion: API_VERSION$
|
|
98
|
+
apiVersion: API_VERSION$5,
|
|
1066
99
|
projectId: instance.config.projectId,
|
|
1067
100
|
dataset: instance.config.dataset
|
|
1068
101
|
}).observable.pipe(switchMap((client) => client.observable.agent.action.generate(options)));
|
|
1069
102
|
}
|
|
1070
103
|
function agentTransform(instance, options) {
|
|
1071
104
|
return getClientState(instance, {
|
|
1072
|
-
apiVersion: API_VERSION$
|
|
105
|
+
apiVersion: API_VERSION$5,
|
|
1073
106
|
projectId: instance.config.projectId,
|
|
1074
107
|
dataset: instance.config.dataset
|
|
1075
108
|
}).observable.pipe(switchMap((client) => client.observable.agent.action.transform(options)));
|
|
1076
109
|
}
|
|
1077
110
|
function agentTranslate(instance, options) {
|
|
1078
111
|
return getClientState(instance, {
|
|
1079
|
-
apiVersion: API_VERSION$
|
|
112
|
+
apiVersion: API_VERSION$5,
|
|
1080
113
|
projectId: instance.config.projectId,
|
|
1081
114
|
dataset: instance.config.dataset
|
|
1082
115
|
}).observable.pipe(switchMap((client) => client.observable.agent.action.translate(options)));
|
|
1083
116
|
}
|
|
1084
117
|
function agentPrompt(instance, options) {
|
|
1085
118
|
return getClientState(instance, {
|
|
1086
|
-
apiVersion: API_VERSION$
|
|
119
|
+
apiVersion: API_VERSION$5,
|
|
1087
120
|
projectId: instance.config.projectId,
|
|
1088
121
|
dataset: instance.config.dataset
|
|
1089
122
|
}).observable.pipe(switchMap((client) => from(client.agent.action.prompt(options))));
|
|
1090
123
|
}
|
|
1091
124
|
function agentPatch(instance, options) {
|
|
1092
125
|
return getClientState(instance, {
|
|
1093
|
-
apiVersion: API_VERSION$
|
|
126
|
+
apiVersion: API_VERSION$5,
|
|
1094
127
|
projectId: instance.config.projectId,
|
|
1095
128
|
dataset: instance.config.dataset
|
|
1096
129
|
}).observable.pipe(switchMap((client) => from(client.agent.action.patch(options))));
|
|
@@ -1107,7 +140,7 @@ function createFetcherStore({
|
|
|
1107
140
|
fetchThrottleInternal = 1e3,
|
|
1108
141
|
stateExpirationDelay = 5e3
|
|
1109
142
|
}) {
|
|
1110
|
-
const store = {
|
|
143
|
+
const store = defineStore({
|
|
1111
144
|
name,
|
|
1112
145
|
getInitialState: () => ({
|
|
1113
146
|
stateByParams: {}
|
|
@@ -1116,7 +149,7 @@ function createFetcherStore({
|
|
|
1116
149
|
const subscription = subscribeToSubscriptionsAndFetch(context);
|
|
1117
150
|
return () => subscription.unsubscribe();
|
|
1118
151
|
}
|
|
1119
|
-
}, subscribeToSubscriptionsAndFetch = ({
|
|
152
|
+
}), subscribeToSubscriptionsAndFetch = ({
|
|
1120
153
|
state
|
|
1121
154
|
}) => state.observable.pipe(
|
|
1122
155
|
// Map the state to an array of [serialized, entry] pairs.
|
|
@@ -1132,13 +165,13 @@ function createFetcherStore({
|
|
|
1132
165
|
startWith([group$.key, void 0]),
|
|
1133
166
|
pairwise(),
|
|
1134
167
|
// Trigger only when the subscriptions array grows.
|
|
1135
|
-
filter
|
|
168
|
+
filter(([[, prevEntry], [, currEntry]]) => {
|
|
1136
169
|
const prevSubs = prevEntry?.subscriptions ?? [];
|
|
1137
170
|
return (currEntry?.subscriptions ?? []).length > prevSubs.length;
|
|
1138
171
|
}),
|
|
1139
|
-
map
|
|
172
|
+
map(([, [, currEntry]]) => currEntry),
|
|
1140
173
|
// Only trigger if we haven't fetched recently.
|
|
1141
|
-
filter
|
|
174
|
+
filter((entry) => {
|
|
1142
175
|
const lastFetch = entry?.lastFetchInitiatedAt;
|
|
1143
176
|
return lastFetch ? Date.now() - new Date(lastFetch).getTime() >= fetchThrottleInternal : !0;
|
|
1144
177
|
}),
|
|
@@ -1208,7 +241,7 @@ function createFetcherStore({
|
|
|
1208
241
|
}
|
|
1209
242
|
}
|
|
1210
243
|
})), () => {
|
|
1211
|
-
|
|
244
|
+
setCleanupTimeout(() => {
|
|
1212
245
|
state.set("removeSubscription", (prev) => {
|
|
1213
246
|
const entry = prev.stateByParams[key];
|
|
1214
247
|
if (!entry) return prev;
|
|
@@ -1233,7 +266,7 @@ function createFetcherStore({
|
|
|
1233
266
|
);
|
|
1234
267
|
return { getState, resolveState };
|
|
1235
268
|
}
|
|
1236
|
-
const API_VERSION$
|
|
269
|
+
const API_VERSION$4 = "v2025-02-19", project = createFetcherStore({
|
|
1237
270
|
name: "Project",
|
|
1238
271
|
getKey: (instance, options) => {
|
|
1239
272
|
const projectId = options?.projectId ?? instance.config.projectId;
|
|
@@ -1244,7 +277,7 @@ const API_VERSION$5 = "v2025-02-19", project = createFetcherStore({
|
|
|
1244
277
|
fetcher: (instance) => (options = {}) => {
|
|
1245
278
|
const projectId = options.projectId ?? instance.config.projectId;
|
|
1246
279
|
return getClientState(instance, {
|
|
1247
|
-
apiVersion: API_VERSION$
|
|
280
|
+
apiVersion: API_VERSION$4,
|
|
1248
281
|
scope: "global",
|
|
1249
282
|
projectId
|
|
1250
283
|
}).observable.pipe(
|
|
@@ -1263,7 +296,7 @@ const API_VERSION$5 = "v2025-02-19", project = createFetcherStore({
|
|
|
1263
296
|
function observeOrganizationVerificationState(instance, projectIds) {
|
|
1264
297
|
const dashboardOrgId$ = getDashboardOrganizationId(instance).observable.pipe(distinctUntilChanged()), projectOrgIdObservables = projectIds.map(
|
|
1265
298
|
(id) => getProjectState(instance, { projectId: id }).observable.pipe(
|
|
1266
|
-
map((project2) => ({ projectId: id, orgId: project2?.organizationId ?? null })),
|
|
299
|
+
map$1((project2) => ({ projectId: id, orgId: project2?.organizationId ?? null })),
|
|
1267
300
|
// Ensure we only proceed if the orgId is loaded, distinct prevents unnecessary checks
|
|
1268
301
|
distinctUntilChanged((prev, curr) => prev.orgId === curr.orgId)
|
|
1269
302
|
)
|
|
@@ -1299,7 +332,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1299
332
|
const cleanedUrl = getCleanedUrl(locationHref), tokenFromUrl = getTokenFromLocation(locationHref);
|
|
1300
333
|
if (tokenFromUrl)
|
|
1301
334
|
return state.set("setTokenFromUrl", {
|
|
1302
|
-
authState:
|
|
335
|
+
authState: createLoggedInAuthState(tokenFromUrl, null)
|
|
1303
336
|
}), cleanedUrl;
|
|
1304
337
|
const authCode = getAuthCode(callbackUrl, locationHref);
|
|
1305
338
|
if (!authCode) return !1;
|
|
@@ -1320,7 +353,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1320
353
|
});
|
|
1321
354
|
try {
|
|
1322
355
|
const client = clientFactory({
|
|
1323
|
-
apiVersion: DEFAULT_API_VERSION
|
|
356
|
+
apiVersion: DEFAULT_API_VERSION,
|
|
1324
357
|
requestTagPrefix: REQUEST_TAG_PREFIX,
|
|
1325
358
|
useProjectHostname: !1,
|
|
1326
359
|
useCdn: !1,
|
|
@@ -1331,7 +364,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1331
364
|
query: { sid: authCode },
|
|
1332
365
|
tag: "fetch-token"
|
|
1333
366
|
});
|
|
1334
|
-
return storageArea?.setItem(storageKey, JSON.stringify({ token })), state.set("setToken", { authState:
|
|
367
|
+
return storageArea?.setItem(storageKey, JSON.stringify({ token })), state.set("setToken", { authState: createLoggedInAuthState(token, null) }), cleanedUrl;
|
|
1335
368
|
} catch (error) {
|
|
1336
369
|
return state.set("exchangeSessionForTokenError", { authState: { type: AuthStateType.ERROR, error } }), cleanedUrl;
|
|
1337
370
|
}
|
|
@@ -1348,11 +381,11 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1348
381
|
}), await clientFactory({
|
|
1349
382
|
token,
|
|
1350
383
|
requestTagPrefix: REQUEST_TAG_PREFIX,
|
|
1351
|
-
apiVersion: DEFAULT_API_VERSION
|
|
384
|
+
apiVersion: DEFAULT_API_VERSION,
|
|
1352
385
|
...apiHost && { apiHost },
|
|
1353
386
|
useProjectHostname: !1,
|
|
1354
387
|
useCdn: !1
|
|
1355
|
-
}).request({ uri: "/auth/logout", method: "POST" }));
|
|
388
|
+
}).request({ uri: "/auth/logout", method: "POST", tag: "logout" }));
|
|
1356
389
|
} finally {
|
|
1357
390
|
state.set("logoutSuccess", {
|
|
1358
391
|
authState: { type: AuthStateType.LOGGED_OUT, isDestroyingSession: !1 }
|
|
@@ -1408,7 +441,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1408
441
|
})
|
|
1409
442
|
});
|
|
1410
443
|
}
|
|
1411
|
-
}, comlinkControllerStore = {
|
|
444
|
+
}, comlinkControllerStore = defineStore({
|
|
1412
445
|
name: "connectionStore",
|
|
1413
446
|
getInitialState: () => ({
|
|
1414
447
|
controller: null,
|
|
@@ -1420,7 +453,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1420
453
|
destroyController(instance);
|
|
1421
454
|
};
|
|
1422
455
|
}
|
|
1423
|
-
}, destroyController = bindActionGlobally(
|
|
456
|
+
}), destroyController = bindActionGlobally(
|
|
1424
457
|
comlinkControllerStore,
|
|
1425
458
|
destroyController$1
|
|
1426
459
|
), getOrCreateChannel = bindActionGlobally(
|
|
@@ -1461,7 +494,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1461
494
|
existing.statusUnsub && existing.statusUnsub(), existing.node.stop(), nodes.delete(name), state.set("removeNode", { nodes });
|
|
1462
495
|
return;
|
|
1463
496
|
}
|
|
1464
|
-
}, comlinkNodeStore = {
|
|
497
|
+
}, comlinkNodeStore = defineStore({
|
|
1465
498
|
name: "nodeStore",
|
|
1466
499
|
getInitialState: () => ({
|
|
1467
500
|
nodes: /* @__PURE__ */ new Map(),
|
|
@@ -1474,7 +507,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1474
507
|
});
|
|
1475
508
|
};
|
|
1476
509
|
}
|
|
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(
|
|
510
|
+
}), 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
511
|
comlinkNodeStore,
|
|
1479
512
|
createStateSourceAction({
|
|
1480
513
|
selector: createSelector([selectNode], (nodeEntry) => nodeEntry?.status === "connected" ? {
|
|
@@ -1486,7 +519,7 @@ const handleAuthCallback = bindActionGlobally(
|
|
|
1486
519
|
getOrCreateNode(instance, nodeInput);
|
|
1487
520
|
let subs = state.get().subscriptions.get(nodeName);
|
|
1488
521
|
return subs || (subs = /* @__PURE__ */ new Set(), state.get().subscriptions.set(nodeName, subs)), subs.add(subscriberId), () => {
|
|
1489
|
-
|
|
522
|
+
setCleanupTimeout(() => {
|
|
1490
523
|
const activeSubs = state.get().subscriptions.get(nodeName);
|
|
1491
524
|
activeSubs && (activeSubs.delete(subscriberId), activeSubs.size === 0 && (state.get().subscriptions.delete(nodeName), releaseNode(instance, nodeName)));
|
|
1492
525
|
}, NODE_RELEASE_TIME);
|
|
@@ -1521,7 +554,7 @@ function configureLogging(config) {
|
|
|
1521
554
|
source: "programmatic"
|
|
1522
555
|
});
|
|
1523
556
|
}
|
|
1524
|
-
const API_VERSION$
|
|
557
|
+
const API_VERSION$3 = "v2025-02-19", datasets = createFetcherStore({
|
|
1525
558
|
name: "Datasets",
|
|
1526
559
|
getKey: (instance, options) => {
|
|
1527
560
|
const projectId = options?.projectId ?? instance.config.projectId;
|
|
@@ -1530,27 +563,31 @@ const API_VERSION$4 = "v2025-02-19", datasets = createFetcherStore({
|
|
|
1530
563
|
return projectId;
|
|
1531
564
|
},
|
|
1532
565
|
fetcher: (instance) => (options) => getClientState(instance, {
|
|
1533
|
-
apiVersion: API_VERSION$
|
|
566
|
+
apiVersion: API_VERSION$3,
|
|
1534
567
|
// non-null assertion is fine because we check above
|
|
1535
568
|
projectId: options?.projectId ?? instance.config.projectId,
|
|
1536
569
|
useProjectHostname: !0
|
|
1537
570
|
}).observable.pipe(switchMap((client) => client.observable.datasets.list()))
|
|
1538
|
-
}), getDatasetsState = datasets.getState, resolveDatasets = datasets.resolveState
|
|
571
|
+
}), getDatasetsState = datasets.getState, resolveDatasets = datasets.resolveState;
|
|
572
|
+
function getEffectiveDocumentId(doc) {
|
|
573
|
+
return doc.liveEdit ? doc.documentId : isReleasePerspective(doc.perspective) ? getVersionId(DocumentId(doc.documentId), doc.perspective.releaseName) : getPublishedId(DocumentId(doc.documentId));
|
|
574
|
+
}
|
|
575
|
+
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
576
|
function createDocument(doc, initialValue) {
|
|
1540
|
-
|
|
577
|
+
let effectiveDocumentId;
|
|
578
|
+
return typeof doc.documentId == "string" && (effectiveDocumentId = getEffectiveDocumentId({ ...doc, documentId: doc.documentId })), {
|
|
1541
579
|
type: "document.create",
|
|
1542
580
|
...doc,
|
|
1543
|
-
...
|
|
1544
|
-
documentId: doc.liveEdit ? doc.documentId : getPublishedId(doc.documentId)
|
|
1545
|
-
},
|
|
581
|
+
...effectiveDocumentId && { documentId: effectiveDocumentId },
|
|
1546
582
|
...initialValue && { initialValue }
|
|
1547
583
|
};
|
|
1548
584
|
}
|
|
1549
585
|
function deleteDocument(doc) {
|
|
586
|
+
const effectiveDocumentId = getEffectiveDocumentId(doc);
|
|
1550
587
|
return {
|
|
1551
588
|
type: "document.delete",
|
|
1552
589
|
...doc,
|
|
1553
|
-
documentId:
|
|
590
|
+
documentId: effectiveDocumentId
|
|
1554
591
|
};
|
|
1555
592
|
}
|
|
1556
593
|
function convertSanityMutatePatch(sanityPatchMutation) {
|
|
@@ -1560,45 +597,48 @@ function convertSanityMutatePatch(sanityPatchMutation) {
|
|
|
1560
597
|
});
|
|
1561
598
|
}
|
|
1562
599
|
function editDocument(doc, patches) {
|
|
1563
|
-
const
|
|
600
|
+
const effectiveDocumentId = getEffectiveDocumentId(doc);
|
|
1564
601
|
if (isSanityMutatePatch(patches)) {
|
|
1565
602
|
const converted = convertSanityMutatePatch(patches) ?? [];
|
|
1566
603
|
return {
|
|
1567
604
|
...doc,
|
|
1568
605
|
type: "document.edit",
|
|
1569
|
-
documentId,
|
|
606
|
+
documentId: effectiveDocumentId,
|
|
1570
607
|
patches: converted
|
|
1571
608
|
};
|
|
1572
609
|
}
|
|
1573
610
|
return {
|
|
1574
611
|
...doc,
|
|
1575
612
|
type: "document.edit",
|
|
1576
|
-
documentId,
|
|
613
|
+
documentId: effectiveDocumentId,
|
|
1577
614
|
...patches && { patches: Array.isArray(patches) ? patches : [patches] }
|
|
1578
615
|
};
|
|
1579
616
|
}
|
|
1580
617
|
function publishDocument(doc) {
|
|
618
|
+
const effectiveDocumentId = getEffectiveDocumentId(doc);
|
|
1581
619
|
return {
|
|
1582
620
|
type: "document.publish",
|
|
1583
621
|
...doc,
|
|
1584
|
-
documentId:
|
|
622
|
+
documentId: effectiveDocumentId
|
|
1585
623
|
};
|
|
1586
624
|
}
|
|
1587
625
|
function unpublishDocument(doc) {
|
|
626
|
+
const effectiveDocumentId = getEffectiveDocumentId(doc);
|
|
1588
627
|
return {
|
|
1589
628
|
type: "document.unpublish",
|
|
1590
629
|
...doc,
|
|
1591
|
-
documentId:
|
|
630
|
+
documentId: effectiveDocumentId
|
|
1592
631
|
};
|
|
1593
632
|
}
|
|
1594
633
|
function discardDocument(doc) {
|
|
634
|
+
const effectiveDocumentId = getEffectiveDocumentId(doc);
|
|
1595
635
|
return {
|
|
1596
636
|
type: "document.discard",
|
|
1597
637
|
...doc,
|
|
1598
|
-
documentId:
|
|
638
|
+
documentId: effectiveDocumentId
|
|
1599
639
|
};
|
|
1600
640
|
}
|
|
1601
|
-
const DOCUMENT_STATE_CLEAR_DELAY = 1e3, INITIAL_OUTGOING_THROTTLE_TIME = 1e3, API_VERSION$
|
|
641
|
+
const DOCUMENT_STATE_CLEAR_DELAY = 1e3, INITIAL_OUTGOING_THROTTLE_TIME = 1e3, API_VERSION$2 = "v2025-05-06";
|
|
1602
642
|
function generateArrayKey(length = 12) {
|
|
1603
643
|
const numBytes = Math.ceil(length / 2), bytes = crypto.getRandomValues(new Uint8Array(numBytes));
|
|
1604
644
|
return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("").slice(0, length);
|
|
@@ -1826,7 +866,7 @@ function processMutations({
|
|
|
1826
866
|
throw new Error(
|
|
1827
867
|
`Cannot create document with \`_id\` \`${id}\` because another document with the same ID already exists.`
|
|
1828
868
|
);
|
|
1829
|
-
const
|
|
869
|
+
const document = {
|
|
1830
870
|
// > `_createdAt` and `_updatedAt` may be submitted and will override
|
|
1831
871
|
// > the default which is of course the current time. This can be used
|
|
1832
872
|
// > to reconstruct a data-set with its timestamp structure intact.
|
|
@@ -1839,11 +879,11 @@ function processMutations({
|
|
|
1839
879
|
_rev: transactionId,
|
|
1840
880
|
_id: id
|
|
1841
881
|
};
|
|
1842
|
-
dataset[id] =
|
|
882
|
+
dataset[id] = document;
|
|
1843
883
|
continue;
|
|
1844
884
|
}
|
|
1845
885
|
if ("createOrReplace" in mutation) {
|
|
1846
|
-
const id = getId(mutation.createOrReplace._id), prev = dataset[id],
|
|
886
|
+
const id = getId(mutation.createOrReplace._id), prev = dataset[id], document = {
|
|
1847
887
|
...mutation.createOrReplace,
|
|
1848
888
|
// otherwise, if the mutation provided, a `_createdAt` time, use it,
|
|
1849
889
|
// otherwise default to now
|
|
@@ -1870,13 +910,13 @@ function processMutations({
|
|
|
1870
910
|
_rev: transactionId,
|
|
1871
911
|
_id: id
|
|
1872
912
|
};
|
|
1873
|
-
dataset[id] =
|
|
913
|
+
dataset[id] = document;
|
|
1874
914
|
continue;
|
|
1875
915
|
}
|
|
1876
916
|
if ("createIfNotExists" in mutation) {
|
|
1877
917
|
const id = getId(mutation.createIfNotExists._id);
|
|
1878
918
|
if (dataset[id]) continue;
|
|
1879
|
-
const
|
|
919
|
+
const document = {
|
|
1880
920
|
// same logic as `create`:
|
|
1881
921
|
// prefer the user's `_createdAt` and `_updatedAt`
|
|
1882
922
|
_createdAt: now,
|
|
@@ -1885,7 +925,7 @@ function processMutations({
|
|
|
1885
925
|
_rev: transactionId,
|
|
1886
926
|
_id: id
|
|
1887
927
|
};
|
|
1888
|
-
dataset[id] =
|
|
928
|
+
dataset[id] = document;
|
|
1889
929
|
continue;
|
|
1890
930
|
}
|
|
1891
931
|
if ("delete" in mutation) {
|
|
@@ -2002,17 +1042,17 @@ const listen = ({ state }, documentId) => {
|
|
|
2002
1042
|
const { sharedListener, fetchDocument } = state.get();
|
|
2003
1043
|
return sharedListener.events.pipe(
|
|
2004
1044
|
concatMap((e) => e.type === "welcome" ? fetchDocument(documentId).pipe(
|
|
2005
|
-
map((
|
|
1045
|
+
map$1((document) => ({ type: "sync", document }))
|
|
2006
1046
|
) : e.type === "mutation" && e.documentId === documentId ? of(e) : EMPTY),
|
|
2007
1047
|
sortListenerEvents(),
|
|
2008
1048
|
withLatestFrom(
|
|
2009
1049
|
state.observable.pipe(
|
|
2010
|
-
map((s) => s.documentStates[documentId]),
|
|
2011
|
-
filter(Boolean),
|
|
1050
|
+
map$1((s) => s.documentStates[documentId]),
|
|
1051
|
+
filter$1(Boolean),
|
|
2012
1052
|
distinctUntilChanged()
|
|
2013
1053
|
)
|
|
2014
1054
|
),
|
|
2015
|
-
map(([next, documentState]) => {
|
|
1055
|
+
map$1(([next, documentState]) => {
|
|
2016
1056
|
if (next.type === "sync")
|
|
2017
1057
|
return {
|
|
2018
1058
|
type: "sync",
|
|
@@ -2021,7 +1061,7 @@ const listen = ({ state }, documentId) => {
|
|
|
2021
1061
|
revision: next.document?._rev,
|
|
2022
1062
|
timestamp: next.document?._updatedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
2023
1063
|
};
|
|
2024
|
-
const [
|
|
1064
|
+
const [document] = Object.values(
|
|
2025
1065
|
processMutations({
|
|
2026
1066
|
documents: { [documentId]: documentState.remote },
|
|
2027
1067
|
mutations: next.mutations,
|
|
@@ -2032,7 +1072,7 @@ const listen = ({ state }, documentId) => {
|
|
|
2032
1072
|
return {
|
|
2033
1073
|
type: "mutation",
|
|
2034
1074
|
documentId,
|
|
2035
|
-
document:
|
|
1075
|
+
document: document ?? null,
|
|
2036
1076
|
revision: transactionId,
|
|
2037
1077
|
timestamp,
|
|
2038
1078
|
...previousRev && { previousRev }
|
|
@@ -2128,7 +1168,15 @@ const documentsCache = new MultiKeyWeakMap(), actionsCache = /* @__PURE__ */ new
|
|
|
2128
1168
|
],
|
|
2129
1169
|
(documentStates, actions) => {
|
|
2130
1170
|
const documentIds = new Set(
|
|
2131
|
-
actions.map((action) =>
|
|
1171
|
+
actions.map((action) => {
|
|
1172
|
+
if (typeof action.documentId != "string") return [];
|
|
1173
|
+
if (action.liveEdit) return [action.documentId];
|
|
1174
|
+
const ids = [
|
|
1175
|
+
getPublishedId(DocumentId(action.documentId)),
|
|
1176
|
+
getDraftId(DocumentId(action.documentId))
|
|
1177
|
+
];
|
|
1178
|
+
return isReleasePerspective(action.perspective) && ids.push(getVersionId(DocumentId(action.documentId), action.perspective.releaseName)), ids;
|
|
1179
|
+
}).flat()
|
|
2132
1180
|
), documents = {};
|
|
2133
1181
|
for (const documentId of documentIds) {
|
|
2134
1182
|
const local = documentStates[documentId]?.local;
|
|
@@ -2155,8 +1203,8 @@ const documentsCache = new MultiKeyWeakMap(), actionsCache = /* @__PURE__ */ new
|
|
|
2155
1203
|
return nestedCache.get(actionsKey) || (nestedCache.set(actionsKey, normalizedActions), normalizedActions);
|
|
2156
1204
|
}
|
|
2157
1205
|
);
|
|
2158
|
-
function checkGrant$1(grantExpr,
|
|
2159
|
-
const value = evaluateSync(grantExpr, { params: { document
|
|
1206
|
+
function checkGrant$1(grantExpr, document) {
|
|
1207
|
+
const value = evaluateSync(grantExpr, { params: { document } });
|
|
2160
1208
|
return value.type === "boolean" && value.data;
|
|
2161
1209
|
}
|
|
2162
1210
|
const enNarrowConjunction = new Intl.ListFormat("en", { style: "narrow", type: "conjunction" });
|
|
@@ -2199,11 +1247,16 @@ const _calculatePermissions = createSelector(
|
|
|
2199
1247
|
}
|
|
2200
1248
|
for (const action of actions)
|
|
2201
1249
|
if (action.type === "document.edit" && !action.patches?.length) {
|
|
2202
|
-
const docId = action.documentId
|
|
2203
|
-
|
|
1250
|
+
const docId = action.documentId;
|
|
1251
|
+
let doc;
|
|
1252
|
+
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
1253
|
type: "access",
|
|
2205
1254
|
message: `You are not allowed to edit the document with ID "${docId}".`,
|
|
2206
1255
|
documentId: docId
|
|
1256
|
+
}) : isReleasePerspective(action.perspective) ? reasons.push({
|
|
1257
|
+
type: "precondition",
|
|
1258
|
+
message: `The version document with ID "${docId}" could not be found. Please create it or add it to the release first.`,
|
|
1259
|
+
documentId: docId
|
|
2207
1260
|
}) : reasons.push({
|
|
2208
1261
|
type: "precondition",
|
|
2209
1262
|
message: `The document with ID "${docId}" could not be found. Please check that it exists before editing.`,
|
|
@@ -2220,8 +1273,8 @@ const _calculatePermissions = createSelector(
|
|
|
2220
1273
|
};
|
|
2221
1274
|
}
|
|
2222
1275
|
);
|
|
2223
|
-
function checkGrant(grantExpr,
|
|
2224
|
-
const value = evaluateSync(grantExpr, { params: { document
|
|
1276
|
+
function checkGrant(grantExpr, document) {
|
|
1277
|
+
const value = evaluateSync(grantExpr, { params: { document } });
|
|
2225
1278
|
return value.type === "boolean" && value.data;
|
|
2226
1279
|
}
|
|
2227
1280
|
class ActionError extends Error {
|
|
@@ -2254,7 +1307,11 @@ function processActions({
|
|
|
2254
1307
|
transactionId,
|
|
2255
1308
|
message: "This document already exists."
|
|
2256
1309
|
});
|
|
2257
|
-
const newDocBase2 = { _type: action.documentType, _id: documentId
|
|
1310
|
+
const newDocBase2 = { _type: action.documentType, _id: documentId, ...action.initialValue }, mutations2 = [{ create: {
|
|
1311
|
+
_type: action.documentType,
|
|
1312
|
+
_id: documentId,
|
|
1313
|
+
...action.initialValue
|
|
1314
|
+
} }];
|
|
2258
1315
|
if (base = processMutations({
|
|
2259
1316
|
documents: base,
|
|
2260
1317
|
transactionId,
|
|
@@ -2271,29 +1328,27 @@ function processActions({
|
|
|
2271
1328
|
transactionId,
|
|
2272
1329
|
message: `You do not have permission to create document "${documentId}".`
|
|
2273
1330
|
});
|
|
2274
|
-
outgoingMutations.push(...mutations2)
|
|
2275
|
-
actionType: "sanity.action.document.create",
|
|
2276
|
-
publishedId: documentId,
|
|
2277
|
-
attributes: newDocWorking2
|
|
2278
|
-
});
|
|
1331
|
+
outgoingMutations.push(...mutations2);
|
|
2279
1332
|
continue;
|
|
2280
1333
|
}
|
|
2281
|
-
const draftId = getDraftId(documentId), publishedId = getPublishedId(documentId);
|
|
2282
|
-
if (working[draftId])
|
|
1334
|
+
const versionId = isReleasePerspective(action.perspective) ? getVersionId(DocumentId(documentId), action.perspective.releaseName) : void 0, draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId));
|
|
1335
|
+
if (versionId ? working[versionId] : working[draftId]) {
|
|
1336
|
+
const errorDocType = versionId ? "release version" : "draft";
|
|
2283
1337
|
throw new ActionError({
|
|
2284
1338
|
documentId,
|
|
2285
1339
|
transactionId,
|
|
2286
|
-
message:
|
|
1340
|
+
message: `A ${errorDocType} of this document already exists. Please use or discard the existing ${errorDocType} before creating a new one.`
|
|
2287
1341
|
});
|
|
1342
|
+
}
|
|
2288
1343
|
const newDocBase = {
|
|
2289
|
-
...base[publishedId],
|
|
1344
|
+
...base[draftId] ?? base[publishedId],
|
|
2290
1345
|
_type: action.documentType,
|
|
2291
|
-
_id: draftId,
|
|
1346
|
+
_id: versionId ?? draftId,
|
|
2292
1347
|
...action.initialValue
|
|
2293
1348
|
}, newDocWorking = {
|
|
2294
|
-
...working[publishedId],
|
|
1349
|
+
...working[draftId] ?? working[publishedId],
|
|
2295
1350
|
_type: action.documentType,
|
|
2296
|
-
_id: draftId,
|
|
1351
|
+
_id: versionId ?? draftId,
|
|
2297
1352
|
...action.initialValue
|
|
2298
1353
|
}, mutations = [{ create: newDocWorking }];
|
|
2299
1354
|
if (base = processMutations({
|
|
@@ -2306,7 +1361,13 @@ function processActions({
|
|
|
2306
1361
|
transactionId,
|
|
2307
1362
|
mutations,
|
|
2308
1363
|
timestamp
|
|
2309
|
-
}), !checkGrant(grants.create, working[
|
|
1364
|
+
}), versionId && !checkGrant(grants.create, working[versionId]))
|
|
1365
|
+
throw new PermissionActionError({
|
|
1366
|
+
documentId,
|
|
1367
|
+
transactionId,
|
|
1368
|
+
message: `You do not have permission to create a release version for document "${documentId}".`
|
|
1369
|
+
});
|
|
1370
|
+
if (!versionId && !checkGrant(grants.create, working[draftId]))
|
|
2310
1371
|
throw new PermissionActionError({
|
|
2311
1372
|
documentId,
|
|
2312
1373
|
transactionId,
|
|
@@ -2321,6 +1382,12 @@ function processActions({
|
|
|
2321
1382
|
}
|
|
2322
1383
|
case "document.delete": {
|
|
2323
1384
|
const documentId = action.documentId;
|
|
1385
|
+
if (isReleasePerspective(action.perspective))
|
|
1386
|
+
throw new ActionError({
|
|
1387
|
+
documentId,
|
|
1388
|
+
transactionId,
|
|
1389
|
+
message: 'Cannot delete a version document. You may want to use the "unpublish" or "discard" actions instead.'
|
|
1390
|
+
});
|
|
2324
1391
|
if (action.liveEdit) {
|
|
2325
1392
|
if (!working[documentId])
|
|
2326
1393
|
throw new ActionError({
|
|
@@ -2335,13 +1402,10 @@ function processActions({
|
|
|
2335
1402
|
message: "You do not have permission to delete this document."
|
|
2336
1403
|
});
|
|
2337
1404
|
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
|
-
});
|
|
1405
|
+
base = processMutations({ documents: base, transactionId, mutations: mutations2, timestamp }), working = processMutations({ documents: working, transactionId, mutations: mutations2, timestamp }), outgoingMutations.push(...mutations2);
|
|
2342
1406
|
continue;
|
|
2343
1407
|
}
|
|
2344
|
-
const draftId = getDraftId(documentId), publishedId = getPublishedId(documentId);
|
|
1408
|
+
const draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId));
|
|
2345
1409
|
if (!working[publishedId])
|
|
2346
1410
|
throw new ActionError({
|
|
2347
1411
|
documentId,
|
|
@@ -2371,14 +1435,14 @@ function processActions({
|
|
|
2371
1435
|
transactionId,
|
|
2372
1436
|
message: `Cannot discard changes for liveEdit document "${documentId}". LiveEdit documents do not support drafts.`
|
|
2373
1437
|
});
|
|
2374
|
-
const
|
|
2375
|
-
if (!working[
|
|
1438
|
+
const versionId = isReleasePerspective(action.perspective) ? getVersionId(DocumentId(documentId), action.perspective.releaseName) : getDraftId(DocumentId(documentId)), mutations = [{ delete: { id: versionId } }];
|
|
1439
|
+
if (!working[versionId])
|
|
2376
1440
|
throw new ActionError({
|
|
2377
1441
|
documentId,
|
|
2378
1442
|
transactionId,
|
|
2379
|
-
message: `There is no draft available to discard for document "${documentId}".`
|
|
1443
|
+
message: `There is no draft or version available to discard for document "${documentId}".`
|
|
2380
1444
|
});
|
|
2381
|
-
if (!checkGrant(grants.update, working[
|
|
1445
|
+
if (!checkGrant(grants.update, working[versionId]))
|
|
2382
1446
|
throw new PermissionActionError({
|
|
2383
1447
|
documentId,
|
|
2384
1448
|
transactionId,
|
|
@@ -2386,7 +1450,7 @@ function processActions({
|
|
|
2386
1450
|
});
|
|
2387
1451
|
base = processMutations({ documents: base, transactionId, mutations, timestamp }), working = processMutations({ documents: working, transactionId, mutations, timestamp }), outgoingMutations.push(...mutations), outgoingActions.push({
|
|
2388
1452
|
actionType: "sanity.action.document.version.discard",
|
|
2389
|
-
versionId
|
|
1453
|
+
versionId
|
|
2390
1454
|
});
|
|
2391
1455
|
continue;
|
|
2392
1456
|
}
|
|
@@ -2421,38 +1485,37 @@ function processActions({
|
|
|
2421
1485
|
transactionId,
|
|
2422
1486
|
mutations: workingMutations2,
|
|
2423
1487
|
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
|
-
);
|
|
1488
|
+
}), outgoingMutations.push(...workingMutations2);
|
|
2435
1489
|
continue;
|
|
2436
1490
|
}
|
|
2437
|
-
const draftId = getDraftId(documentId), publishedId = getPublishedId(documentId), userPatches = action.patches?.map((patch) => ({
|
|
1491
|
+
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) => ({
|
|
1492
|
+
patch: { id: patchDocumentId, ...patch }
|
|
1493
|
+
}));
|
|
2438
1494
|
if (!userPatches?.length) continue;
|
|
2439
|
-
if (
|
|
1495
|
+
if (isReleasePerspective(action.perspective)) {
|
|
1496
|
+
if (!working[versionId] && !base[versionId])
|
|
1497
|
+
throw new ActionError({
|
|
1498
|
+
documentId,
|
|
1499
|
+
transactionId,
|
|
1500
|
+
message: "This document does not exist in the release. Please create it or add it to the release first."
|
|
1501
|
+
});
|
|
1502
|
+
} else if (!working[draftId] && !working[publishedId] || !base[draftId] && !base[publishedId])
|
|
2440
1503
|
throw new ActionError({
|
|
2441
1504
|
documentId,
|
|
2442
1505
|
transactionId,
|
|
2443
1506
|
message: "Cannot edit document because it does not exist in draft or published form."
|
|
2444
1507
|
});
|
|
2445
1508
|
const baseMutations = [];
|
|
2446
|
-
!base[draftId] && base[publishedId] && baseMutations.push({ create: { ...base[publishedId], _id: draftId } });
|
|
2447
|
-
const baseBefore = base[
|
|
1509
|
+
!isReleasePerspective(action.perspective) && !base[draftId] && base[publishedId] && baseMutations.push({ create: { ...base[publishedId], _id: draftId } });
|
|
1510
|
+
const baseBefore = base[patchDocumentId] ?? base[publishedId];
|
|
2448
1511
|
userPatches && baseMutations.push(...userPatches), base = processMutations({
|
|
2449
1512
|
documents: base,
|
|
2450
1513
|
transactionId,
|
|
2451
1514
|
mutations: baseMutations,
|
|
2452
1515
|
timestamp
|
|
2453
1516
|
});
|
|
2454
|
-
const baseAfter = base[
|
|
2455
|
-
if (!working[draftId] && working[publishedId]) {
|
|
1517
|
+
const baseAfter = base[patchDocumentId], patches = diffValue(baseBefore, baseAfter), workingMutations = [];
|
|
1518
|
+
if (!isReleasePerspective(action.perspective) && !working[draftId] && working[publishedId]) {
|
|
2456
1519
|
const newDraftFromPublished = { ...working[publishedId], _id: draftId };
|
|
2457
1520
|
if (!checkGrant(grants.create, newDraftFromPublished))
|
|
2458
1521
|
throw new PermissionActionError({
|
|
@@ -2462,39 +1525,37 @@ function processActions({
|
|
|
2462
1525
|
});
|
|
2463
1526
|
workingMutations.push({ create: newDraftFromPublished });
|
|
2464
1527
|
}
|
|
2465
|
-
const workingBefore = working[
|
|
1528
|
+
const workingBefore = working[patchDocumentId] ?? working[publishedId];
|
|
2466
1529
|
if (!checkGrant(grants.update, workingBefore))
|
|
2467
1530
|
throw new PermissionActionError({
|
|
2468
1531
|
documentId,
|
|
2469
1532
|
transactionId,
|
|
2470
1533
|
message: `You do not have permission to edit document "${documentId}".`
|
|
2471
1534
|
});
|
|
2472
|
-
workingMutations.push(...patches.map((patch) => ({ patch: { id:
|
|
1535
|
+
workingMutations.push(...patches.map((patch) => ({ patch: { id: patchDocumentId, ...patch } }))), working = processMutations({
|
|
2473
1536
|
documents: working,
|
|
2474
1537
|
transactionId,
|
|
2475
1538
|
mutations: workingMutations,
|
|
2476
1539
|
timestamp
|
|
2477
1540
|
}), outgoingMutations.push(...workingMutations), outgoingActions.push(
|
|
2478
|
-
...patches.map(
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
})
|
|
2485
|
-
)
|
|
1541
|
+
...patches.map((patch) => ({
|
|
1542
|
+
actionType: "sanity.action.document.edit",
|
|
1543
|
+
draftId: patchDocumentId,
|
|
1544
|
+
publishedId,
|
|
1545
|
+
patch
|
|
1546
|
+
}))
|
|
2486
1547
|
);
|
|
2487
1548
|
continue;
|
|
2488
1549
|
}
|
|
2489
1550
|
case "document.publish": {
|
|
2490
1551
|
const documentId = getId(action.documentId);
|
|
2491
|
-
if (action.liveEdit)
|
|
1552
|
+
if (action.liveEdit || isReleasePerspective(action.perspective))
|
|
2492
1553
|
throw new ActionError({
|
|
2493
1554
|
documentId,
|
|
2494
1555
|
transactionId,
|
|
2495
|
-
message:
|
|
1556
|
+
message: "Cannot publish this document. Publishing is not supported for liveEdit or version (release) documents."
|
|
2496
1557
|
});
|
|
2497
|
-
const draftId = getDraftId(documentId), publishedId = getPublishedId(documentId), workingDraft = working[draftId], baseDraft = base[draftId];
|
|
1558
|
+
const draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId)), workingDraft = working[draftId], baseDraft = base[draftId];
|
|
2498
1559
|
if (!workingDraft || !baseDraft)
|
|
2499
1560
|
throw new ActionError({
|
|
2500
1561
|
documentId,
|
|
@@ -2538,13 +1599,13 @@ function processActions({
|
|
|
2538
1599
|
}
|
|
2539
1600
|
case "document.unpublish": {
|
|
2540
1601
|
const documentId = getId(action.documentId);
|
|
2541
|
-
if (action.liveEdit)
|
|
1602
|
+
if (action.liveEdit || isReleasePerspective(action.perspective))
|
|
2542
1603
|
throw new ActionError({
|
|
2543
1604
|
documentId,
|
|
2544
1605
|
transactionId,
|
|
2545
|
-
message:
|
|
1606
|
+
message: "Cannot unpublish this document. Unpublishing is not supported for liveEdit or version (release) documents."
|
|
2546
1607
|
});
|
|
2547
|
-
const draftId = getDraftId(documentId), publishedId = getPublishedId(documentId);
|
|
1608
|
+
const draftId = getDraftId(DocumentId(documentId)), publishedId = getPublishedId(DocumentId(documentId));
|
|
2548
1609
|
if (!working[publishedId] && !base[publishedId])
|
|
2549
1610
|
throw new ActionError({
|
|
2550
1611
|
documentId,
|
|
@@ -2618,7 +1679,7 @@ const EMPTY_REVISIONS = {};
|
|
|
2618
1679
|
function queueTransaction(prev, transaction) {
|
|
2619
1680
|
const { transactionId, actions } = transaction;
|
|
2620
1681
|
return {
|
|
2621
|
-
...
|
|
1682
|
+
...getDocumentIdsFromHandleLikes(actions).reduce(
|
|
2622
1683
|
(acc, id) => addSubscriptionIdToDocument(acc, id, transactionId),
|
|
2623
1684
|
prev
|
|
2624
1685
|
),
|
|
@@ -2628,7 +1689,7 @@ function queueTransaction(prev, transaction) {
|
|
|
2628
1689
|
function removeQueuedTransaction(prev, transactionId) {
|
|
2629
1690
|
const transaction = prev.queued.find((t) => t.transactionId === transactionId);
|
|
2630
1691
|
return transaction ? {
|
|
2631
|
-
...
|
|
1692
|
+
...getDocumentIdsFromHandleLikes(transaction.actions).reduce(
|
|
2632
1693
|
(acc, id) => removeSubscriptionIdFromDocument(acc, id, transactionId),
|
|
2633
1694
|
prev
|
|
2634
1695
|
),
|
|
@@ -2638,7 +1699,7 @@ function removeQueuedTransaction(prev, transactionId) {
|
|
|
2638
1699
|
function applyFirstQueuedTransaction(prev) {
|
|
2639
1700
|
const queued = prev.queued.at(0);
|
|
2640
1701
|
if (!queued || !prev.grants) return prev;
|
|
2641
|
-
const ids =
|
|
1702
|
+
const ids = getDocumentIdsFromHandleLikes(queued.actions);
|
|
2642
1703
|
if (ids.some((id) => prev.documentStates[id]?.local === void 0)) return prev;
|
|
2643
1704
|
const working = ids.reduce((acc, id) => (acc[id] = prev.documentStates[id]?.local, acc), {}), timestamp = (/* @__PURE__ */ new Date()).toISOString(), result = processActions({
|
|
2644
1705
|
...queued,
|
|
@@ -2690,7 +1751,7 @@ function batchAppliedTransactions([curr, ...rest]) {
|
|
|
2690
1751
|
if (!rest.length) return editAction;
|
|
2691
1752
|
const next = batchAppliedTransactions(rest);
|
|
2692
1753
|
if (next)
|
|
2693
|
-
return next.disableBatching ? editAction : {
|
|
1754
|
+
return next.disableBatching || !!action.liveEdit != !!next.actions[0]?.liveEdit ? editAction : {
|
|
2694
1755
|
disableBatching: !1,
|
|
2695
1756
|
// Use the transactionId from the later (next) transaction.
|
|
2696
1757
|
transactionId: next.transactionId,
|
|
@@ -2748,7 +1809,7 @@ function cleanupOutgoingTransaction(prev) {
|
|
|
2748
1809
|
const { outgoing } = prev;
|
|
2749
1810
|
if (!outgoing) return prev;
|
|
2750
1811
|
let next = prev;
|
|
2751
|
-
const ids =
|
|
1812
|
+
const ids = getDocumentIdsFromHandleLikes(outgoing.actions);
|
|
2752
1813
|
for (const transactionId of outgoing.batchedTransactionIds)
|
|
2753
1814
|
for (const documentId of ids)
|
|
2754
1815
|
next = removeSubscriptionIdFromDocument(next, documentId, transactionId);
|
|
@@ -2787,7 +1848,7 @@ function revertOutgoingTransaction(prev) {
|
|
|
2787
1848
|
)
|
|
2788
1849
|
};
|
|
2789
1850
|
}
|
|
2790
|
-
function applyRemoteDocument(prev, { document
|
|
1851
|
+
function applyRemoteDocument(prev, { document, documentId, previousRev, revision, timestamp, type }, events) {
|
|
2791
1852
|
if (!prev.grants) return prev;
|
|
2792
1853
|
const prevDocState = prev.documentStates[documentId];
|
|
2793
1854
|
if (!prevDocState) return prev;
|
|
@@ -2802,13 +1863,13 @@ function applyRemoteDocument(prev, { document: document2, documentId, previousRe
|
|
|
2802
1863
|
...prev.documentStates,
|
|
2803
1864
|
[documentId]: {
|
|
2804
1865
|
...prevDocState,
|
|
2805
|
-
remote:
|
|
1866
|
+
remote: document,
|
|
2806
1867
|
remoteRev: revision,
|
|
2807
1868
|
unverifiedRevisions
|
|
2808
1869
|
}
|
|
2809
1870
|
}
|
|
2810
1871
|
};
|
|
2811
|
-
let working = { ...prev.applied.at(0)?.previous, [documentId]:
|
|
1872
|
+
let working = { ...prev.applied.at(0)?.previous, [documentId]: document };
|
|
2812
1873
|
const nextApplied = [];
|
|
2813
1874
|
for (const curr of prev.applied)
|
|
2814
1875
|
try {
|
|
@@ -2834,7 +1895,7 @@ function applyRemoteDocument(prev, { document: document2, documentId, previousRe
|
|
|
2834
1895
|
...prev.documentStates,
|
|
2835
1896
|
[documentId]: {
|
|
2836
1897
|
...prevDocState,
|
|
2837
|
-
remote:
|
|
1898
|
+
remote: document,
|
|
2838
1899
|
remoteRev: revision,
|
|
2839
1900
|
local: working[documentId],
|
|
2840
1901
|
unverifiedRevisions
|
|
@@ -2866,15 +1927,8 @@ function removeSubscriptionIdFromDocument(prev, documentId, subscriptionId) {
|
|
|
2866
1927
|
}
|
|
2867
1928
|
} : { ...prev, documentStates: omit(prev.documentStates, documentId) } : prev;
|
|
2868
1929
|
}
|
|
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();
|
|
1930
|
+
function manageSubscriberIds({ state }, handles) {
|
|
1931
|
+
const documentIds = getDocumentIdsFromHandleLikes(handles), subscriptionId = insecureRandomId();
|
|
2878
1932
|
return state.set(
|
|
2879
1933
|
"addSubscribers",
|
|
2880
1934
|
(prev) => documentIds.reduce(
|
|
@@ -2882,7 +1936,7 @@ function manageSubscriberIds({ state }, documentId, options) {
|
|
|
2882
1936
|
prev
|
|
2883
1937
|
)
|
|
2884
1938
|
), () => {
|
|
2885
|
-
|
|
1939
|
+
setCleanupTimeout(() => {
|
|
2886
1940
|
state.set(
|
|
2887
1941
|
"removeSubscribers",
|
|
2888
1942
|
(prev) => documentIds.reduce(
|
|
@@ -2893,12 +1947,13 @@ function manageSubscriberIds({ state }, documentId, options) {
|
|
|
2893
1947
|
}, DOCUMENT_STATE_CLEAR_DELAY);
|
|
2894
1948
|
};
|
|
2895
1949
|
}
|
|
2896
|
-
function
|
|
2897
|
-
return
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
1950
|
+
function getDocumentIdsFromHandleLikes(handles) {
|
|
1951
|
+
return handles.flatMap((handle) => {
|
|
1952
|
+
const idsForDocument = [];
|
|
1953
|
+
return handle.documentId ? handle.liveEdit ? [handle.documentId] : (isReleasePerspective(handle.perspective) && idsForDocument.push(
|
|
1954
|
+
getVersionId(DocumentId(handle.documentId), handle.perspective.releaseName)
|
|
1955
|
+
), idsForDocument.push(getPublishedId(DocumentId(handle.documentId))), idsForDocument.push(getDraftId(DocumentId(handle.documentId))), idsForDocument) : [];
|
|
1956
|
+
});
|
|
2902
1957
|
}
|
|
2903
1958
|
function getDocumentEvents(outgoing) {
|
|
2904
1959
|
const documentIdsByAction = Object.entries(
|
|
@@ -2923,10 +1978,12 @@ function getDocumentEvents(outgoing) {
|
|
|
2923
1978
|
)
|
|
2924
1979
|
);
|
|
2925
1980
|
}
|
|
2926
|
-
const API_VERSION$
|
|
2927
|
-
function createSharedListener(instance) {
|
|
1981
|
+
const API_VERSION$1 = "v2025-05-06";
|
|
1982
|
+
function createSharedListener(instance, source) {
|
|
2928
1983
|
const dispose$ = new Subject(), events$ = getClientState(instance, {
|
|
2929
|
-
apiVersion: API_VERSION$
|
|
1984
|
+
apiVersion: API_VERSION$1,
|
|
1985
|
+
// TODO: remove in v3 when we're ready for everything to be queried via source
|
|
1986
|
+
source: source && !isDatasetSource(source) ? source : void 0
|
|
2930
1987
|
}).observable.pipe(
|
|
2931
1988
|
switchMap(
|
|
2932
1989
|
(client) => (
|
|
@@ -2960,11 +2017,15 @@ function createSharedListener(instance) {
|
|
|
2960
2017
|
dispose: () => dispose$.next()
|
|
2961
2018
|
};
|
|
2962
2019
|
}
|
|
2963
|
-
function createFetchDocument(instance) {
|
|
2020
|
+
function createFetchDocument(instance, source) {
|
|
2964
2021
|
return function(documentId) {
|
|
2965
|
-
return getClientState(instance, {
|
|
2022
|
+
return getClientState(instance, {
|
|
2023
|
+
apiVersion: API_VERSION$1,
|
|
2024
|
+
// TODO: remove in v3 when we're ready for everything to be queried via source
|
|
2025
|
+
source: source && !isDatasetSource(source) ? source : void 0
|
|
2026
|
+
}).observable.pipe(
|
|
2966
2027
|
switchMap((client) => createDocumentLoaderFromClient(client)(documentId)),
|
|
2967
|
-
map((result) => {
|
|
2028
|
+
map$1((result) => {
|
|
2968
2029
|
if (!result.accessible) {
|
|
2969
2030
|
if (result.reason === "existence") return null;
|
|
2970
2031
|
throw new Error(`Document with ID \`${documentId}\` is inaccessible due to permissions.`);
|
|
@@ -2975,15 +2036,15 @@ function createFetchDocument(instance) {
|
|
|
2975
2036
|
);
|
|
2976
2037
|
};
|
|
2977
2038
|
}
|
|
2978
|
-
const documentStore = {
|
|
2039
|
+
const documentStore = defineStore({
|
|
2979
2040
|
name: "Document",
|
|
2980
|
-
getInitialState: (instance) => ({
|
|
2041
|
+
getInitialState: (instance, { source }) => ({
|
|
2981
2042
|
documentStates: {},
|
|
2982
2043
|
// these can be emptied on refetch
|
|
2983
2044
|
queued: [],
|
|
2984
2045
|
applied: [],
|
|
2985
|
-
sharedListener: createSharedListener(instance),
|
|
2986
|
-
fetchDocument: createFetchDocument(instance),
|
|
2046
|
+
sharedListener: createSharedListener(instance, source),
|
|
2047
|
+
fetchDocument: createFetchDocument(instance, source),
|
|
2987
2048
|
events: new Subject()
|
|
2988
2049
|
}),
|
|
2989
2050
|
initialize(context) {
|
|
@@ -2997,83 +2058,92 @@ const documentStore = {
|
|
|
2997
2058
|
sharedListener.dispose(), subscriptions.forEach((subscription) => subscription.unsubscribe());
|
|
2998
2059
|
};
|
|
2999
2060
|
}
|
|
3000
|
-
};
|
|
2061
|
+
});
|
|
3001
2062
|
function getDocumentState(...args) {
|
|
3002
2063
|
return _getDocumentState(...args);
|
|
3003
2064
|
}
|
|
3004
|
-
const _getDocumentState =
|
|
2065
|
+
const _getDocumentState = bindActionBySource(
|
|
3005
2066
|
documentStore,
|
|
3006
2067
|
createStateSourceAction({
|
|
3007
2068
|
selector: ({ state: { error, documentStates } }, options) => {
|
|
3008
|
-
const { documentId, path, liveEdit } = options;
|
|
2069
|
+
const { documentId: docId, path, liveEdit, perspective } = options, documentId = DocumentId(docId);
|
|
3009
2070
|
if (error) throw error;
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
if (
|
|
3016
|
-
|
|
3017
|
-
|
|
2071
|
+
let document;
|
|
2072
|
+
if (liveEdit)
|
|
2073
|
+
document = documentStates[documentId]?.local;
|
|
2074
|
+
else {
|
|
2075
|
+
let version;
|
|
2076
|
+
if (isReleasePerspective(perspective)) {
|
|
2077
|
+
const versionId = getVersionId(documentId, perspective.releaseName);
|
|
2078
|
+
if (version = documentStates[versionId]?.local, version === void 0) return;
|
|
2079
|
+
}
|
|
2080
|
+
const draft = documentStates[getDraftId(documentId)]?.local, published = documentStates[getPublishedId(documentId)]?.local;
|
|
2081
|
+
if (draft === void 0 || published === void 0) return;
|
|
2082
|
+
document = version ?? draft ?? published;
|
|
3018
2083
|
}
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
const document2 = draft ?? published;
|
|
3022
|
-
if (!path) return document2;
|
|
3023
|
-
const result = jsonMatch(document2, path).next();
|
|
2084
|
+
if (!path) return document;
|
|
2085
|
+
const result = jsonMatch(document, path).next();
|
|
3024
2086
|
if (result.done) return;
|
|
3025
2087
|
const { value } = result.value;
|
|
3026
2088
|
return value;
|
|
3027
2089
|
},
|
|
3028
|
-
onSubscribe: (context, options) => manageSubscriberIds(context, options
|
|
2090
|
+
onSubscribe: (context, options) => manageSubscriberIds(context, [options])
|
|
3029
2091
|
})
|
|
3030
2092
|
);
|
|
3031
2093
|
function resolveDocument(...args) {
|
|
3032
2094
|
return _resolveDocument(...args);
|
|
3033
2095
|
}
|
|
3034
|
-
const _resolveDocument =
|
|
2096
|
+
const _resolveDocument = bindActionBySource(
|
|
3035
2097
|
documentStore,
|
|
3036
2098
|
({ instance }, docHandle) => firstValueFrom(
|
|
3037
2099
|
getDocumentState(instance, {
|
|
3038
2100
|
...docHandle,
|
|
3039
2101
|
path: void 0
|
|
3040
|
-
}).observable.pipe(filter((i) => i !== void 0))
|
|
2102
|
+
}).observable.pipe(filter$1((i) => i !== void 0))
|
|
3041
2103
|
)
|
|
3042
|
-
), getDocumentSyncStatus =
|
|
2104
|
+
), getDocumentSyncStatus = bindActionBySource(
|
|
3043
2105
|
documentStore,
|
|
3044
2106
|
createStateSourceAction({
|
|
3045
2107
|
selector: ({ state: { error, documentStates: documents, outgoing, applied, queued } }, doc) => {
|
|
3046
|
-
const documentId = typeof doc == "string" ? doc : doc.documentId;
|
|
2108
|
+
const documentId = DocumentId(typeof doc == "string" ? doc : doc.documentId);
|
|
3047
2109
|
if (error) throw error;
|
|
3048
|
-
if (doc.liveEdit)
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
2110
|
+
if (doc.liveEdit) {
|
|
2111
|
+
if (documents[documentId] === void 0) return;
|
|
2112
|
+
} else {
|
|
2113
|
+
const version = isReleasePerspective(doc.perspective) ? documents[getVersionId(documentId, doc.perspective.releaseName)] : void 0;
|
|
2114
|
+
if (isReleasePerspective(doc.perspective) && version === void 0) return;
|
|
2115
|
+
const draft = documents[getDraftId(documentId)], published = documents[getPublishedId(documentId)];
|
|
2116
|
+
if (draft === void 0 || published === void 0) return;
|
|
2117
|
+
}
|
|
2118
|
+
return !queued.length && !applied.length && !outgoing;
|
|
3053
2119
|
},
|
|
3054
|
-
onSubscribe: (context, doc) => manageSubscriberIds(context, doc
|
|
2120
|
+
onSubscribe: (context, doc) => manageSubscriberIds(context, [doc])
|
|
3055
2121
|
})
|
|
3056
|
-
), getPermissionsState =
|
|
2122
|
+
), getPermissionsState = bindActionBySource(
|
|
3057
2123
|
documentStore,
|
|
3058
2124
|
createStateSourceAction({
|
|
3059
2125
|
selector: calculatePermissions,
|
|
3060
|
-
onSubscribe: (context, { actions }) =>
|
|
2126
|
+
onSubscribe: (context, { actions }) => {
|
|
2127
|
+
manageSubscriberIds(context, actions);
|
|
2128
|
+
}
|
|
3061
2129
|
})
|
|
3062
|
-
), resolvePermissions =
|
|
2130
|
+
), resolvePermissions = bindActionBySource(
|
|
3063
2131
|
documentStore,
|
|
3064
2132
|
({ instance }, options) => firstValueFrom(
|
|
3065
|
-
getPermissionsState(instance, options).observable.pipe(filter((i) => i !== void 0))
|
|
2133
|
+
getPermissionsState(instance, options).observable.pipe(filter$1((i) => i !== void 0))
|
|
3066
2134
|
)
|
|
3067
|
-
), subscribeDocumentEvents =
|
|
2135
|
+
), subscribeDocumentEvents = bindActionBySource(
|
|
3068
2136
|
documentStore,
|
|
3069
|
-
({ state },
|
|
3070
|
-
const { events } = state.get(), subscription = events.subscribe(eventHandler);
|
|
2137
|
+
({ state }, options) => {
|
|
2138
|
+
const { events } = state.get(), subscription = events.subscribe(options.eventHandler);
|
|
3071
2139
|
return () => subscription.unsubscribe();
|
|
3072
2140
|
}
|
|
3073
|
-
), subscribeToQueuedAndApplyNextTransaction = ({
|
|
2141
|
+
), subscribeToQueuedAndApplyNextTransaction = ({
|
|
2142
|
+
state
|
|
2143
|
+
}) => {
|
|
3074
2144
|
const { events } = state.get();
|
|
3075
2145
|
return state.observable.pipe(
|
|
3076
|
-
map(applyFirstQueuedTransaction),
|
|
2146
|
+
map$1(applyFirstQueuedTransaction),
|
|
3077
2147
|
distinctUntilChanged(),
|
|
3078
2148
|
tap$1((next) => state.set("applyFirstQueuedTransaction", next)),
|
|
3079
2149
|
catchError$1((error, caught) => {
|
|
@@ -3093,7 +2163,8 @@ const _resolveDocument = bindActionByDataset(
|
|
|
3093
2163
|
).subscribe({ error: (error) => state.set("setError", { error }) });
|
|
3094
2164
|
}, subscribeToAppliedAndSubmitNextTransaction = ({
|
|
3095
2165
|
state,
|
|
3096
|
-
instance
|
|
2166
|
+
instance,
|
|
2167
|
+
key: { source }
|
|
3097
2168
|
}) => {
|
|
3098
2169
|
const { events } = state.get();
|
|
3099
2170
|
return state.observable.pipe(
|
|
@@ -3108,19 +2179,41 @@ const _resolveDocument = bindActionByDataset(
|
|
|
3108
2179
|
),
|
|
3109
2180
|
{ leading: !1, trailing: !0 }
|
|
3110
2181
|
),
|
|
3111
|
-
map(transitionAppliedTransactionsToOutgoing),
|
|
2182
|
+
map$1(transitionAppliedTransactionsToOutgoing),
|
|
3112
2183
|
distinctUntilChanged((a, b) => a.outgoing?.transactionId === b.outgoing?.transactionId),
|
|
3113
2184
|
tap$1((next) => state.set("transitionAppliedTransactionsToOutgoing", next)),
|
|
3114
|
-
map((s) => s.outgoing),
|
|
2185
|
+
map$1((s) => s.outgoing),
|
|
3115
2186
|
distinctUntilChanged(),
|
|
3116
|
-
withLatestFrom(
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
)
|
|
2187
|
+
withLatestFrom(
|
|
2188
|
+
getClientState(instance, {
|
|
2189
|
+
apiVersion: API_VERSION$2,
|
|
2190
|
+
// TODO: remove in v3 when we're ready for everything to be queried via source
|
|
2191
|
+
source: source && !isDatasetSource(source) ? source : void 0
|
|
2192
|
+
}).observable
|
|
2193
|
+
),
|
|
2194
|
+
concatMap(([outgoing, client]) => {
|
|
2195
|
+
if (!outgoing) return EMPTY;
|
|
2196
|
+
const revertOnError = catchError$1((error) => {
|
|
2197
|
+
state.set("revertOutgoingTransaction", revertOutgoingTransaction);
|
|
2198
|
+
const message = error instanceof Error ? error.message : "Request failed";
|
|
2199
|
+
return events.next({ type: "reverted", message, outgoing, error }), EMPTY;
|
|
2200
|
+
}), toResult = map$1((result) => ({
|
|
2201
|
+
result,
|
|
2202
|
+
outgoing
|
|
2203
|
+
}));
|
|
2204
|
+
return outgoing.actions.some((action) => action.liveEdit) ? client.observable.mutate(outgoing.outgoingMutations, {
|
|
2205
|
+
transactionId: outgoing.transactionId,
|
|
2206
|
+
visibility: "async",
|
|
2207
|
+
returnDocuments: !1,
|
|
2208
|
+
returnFirst: !1,
|
|
2209
|
+
tag: "document.mutate",
|
|
2210
|
+
skipCrossDatasetReferenceValidation: !0
|
|
2211
|
+
}).pipe(revertOnError, toResult) : client.observable.action(outgoing.outgoingActions, {
|
|
2212
|
+
transactionId: outgoing.transactionId,
|
|
2213
|
+
skipCrossDatasetReferenceValidation: !0,
|
|
2214
|
+
tag: "document.action"
|
|
2215
|
+
}).pipe(revertOnError, toResult);
|
|
2216
|
+
}),
|
|
3124
2217
|
tap$1(({ outgoing, result }) => {
|
|
3125
2218
|
state.set("cleanupOutgoingTransaction", cleanupOutgoingTransaction);
|
|
3126
2219
|
for (const e of getDocumentEvents(outgoing)) events.next(e);
|
|
@@ -3130,8 +2223,8 @@ const _resolveDocument = bindActionByDataset(
|
|
|
3130
2223
|
}, subscribeToSubscriptionsAndListenToDocuments = (context) => {
|
|
3131
2224
|
const { state } = context, { events } = state.get();
|
|
3132
2225
|
return state.observable.pipe(
|
|
3133
|
-
filter((s) => !!s.grants),
|
|
3134
|
-
map((s) => Object.keys(s.documentStates)),
|
|
2226
|
+
filter$1((s) => !!s.grants),
|
|
2227
|
+
map$1((s) => Object.keys(s.documentStates)),
|
|
3135
2228
|
distinctUntilChanged((curr, next) => {
|
|
3136
2229
|
if (curr.length !== next.length) return !1;
|
|
3137
2230
|
const currSet = new Set(curr);
|
|
@@ -3144,7 +2237,7 @@ const _resolveDocument = bindActionByDataset(
|
|
|
3144
2237
|
...added.map((id) => ({ id, add: !0 })),
|
|
3145
2238
|
...removed.map((id) => ({ id, add: !1 }))
|
|
3146
2239
|
].sort((a, b) => {
|
|
3147
|
-
const aIsDraft = a.id === getDraftId(a.id), bIsDraft = b.id === getDraftId(b.id);
|
|
2240
|
+
const aIsDraft = a.id === getDraftId(DocumentId(a.id)), bIsDraft = b.id === getDraftId(DocumentId(b.id));
|
|
3148
2241
|
return aIsDraft && bIsDraft ? a.id.localeCompare(b.id, "en-US") : aIsDraft ? -1 : bIsDraft ? 1 : a.id.localeCompare(b.id, "en-US");
|
|
3149
2242
|
});
|
|
3150
2243
|
return of(...changes);
|
|
@@ -3169,45 +2262,58 @@ const _resolveDocument = bindActionByDataset(
|
|
|
3169
2262
|
}, subscribeToClientAndFetchDatasetAcl = ({
|
|
3170
2263
|
instance,
|
|
3171
2264
|
state,
|
|
3172
|
-
key: {
|
|
3173
|
-
}) =>
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
});
|
|
2265
|
+
key: { source }
|
|
2266
|
+
}) => {
|
|
2267
|
+
const clientOptions = { apiVersion: API_VERSION$2 };
|
|
2268
|
+
source && !isDatasetSource(source) && (clientOptions.source = source);
|
|
2269
|
+
let uri;
|
|
2270
|
+
if (source && isDatasetSource(source))
|
|
2271
|
+
uri = `/projects/${source.projectId}/datasets/${source.dataset}/acl`;
|
|
2272
|
+
else if (source && isMediaLibrarySource(source))
|
|
2273
|
+
uri = `/media-libraries/${source.mediaLibraryId}/acl`;
|
|
2274
|
+
else if (source && isCanvasSource(source))
|
|
2275
|
+
uri = `/canvases/${source.canvasId}/acl`;
|
|
2276
|
+
else
|
|
2277
|
+
throw new Error(`Received invalid source: ${JSON.stringify(source)}`);
|
|
2278
|
+
return getClientState(instance, clientOptions).observable.pipe(
|
|
2279
|
+
switchMap(
|
|
2280
|
+
(client) => client.observable.request({
|
|
2281
|
+
uri,
|
|
2282
|
+
tag: "acl.get",
|
|
2283
|
+
withCredentials: !0
|
|
2284
|
+
})
|
|
2285
|
+
),
|
|
2286
|
+
tap$1((datasetAcl) => state.set("setGrants", { grants: createGrantsLookup(datasetAcl) }))
|
|
2287
|
+
).subscribe({
|
|
2288
|
+
error: (error) => state.set("setError", { error })
|
|
2289
|
+
});
|
|
2290
|
+
};
|
|
3185
2291
|
function applyDocumentActions(...args) {
|
|
3186
2292
|
return boundApplyDocumentActions(...args);
|
|
3187
2293
|
}
|
|
3188
|
-
const boundApplyDocumentActions =
|
|
2294
|
+
const boundApplyDocumentActions = bindActionBySource(documentStore, _applyDocumentActions);
|
|
3189
2295
|
async function _applyDocumentActions({ state }, { actions, transactionId = crypto.randomUUID(), disableBatching }) {
|
|
3190
2296
|
const { events } = state.get(), transaction = {
|
|
3191
2297
|
transactionId,
|
|
3192
2298
|
actions,
|
|
3193
2299
|
...disableBatching && { disableBatching }
|
|
3194
2300
|
}, fatalError$ = state.observable.pipe(
|
|
3195
|
-
map((s) => s.error),
|
|
2301
|
+
map$1((s) => s.error),
|
|
3196
2302
|
first$1(Boolean),
|
|
3197
|
-
map((error) => ({ type: "error", error }))
|
|
2303
|
+
map$1((error) => ({ type: "error", error }))
|
|
3198
2304
|
), transactionError$ = events.pipe(
|
|
3199
|
-
filter((e) => e.type === "error"),
|
|
2305
|
+
filter$1((e) => e.type === "error"),
|
|
3200
2306
|
first$1((e) => e.transactionId === transactionId)
|
|
3201
2307
|
), appliedTransaction$ = state.observable.pipe(
|
|
3202
|
-
map((s) => s.applied),
|
|
2308
|
+
map$1((s) => s.applied),
|
|
3203
2309
|
distinctUntilChanged(),
|
|
3204
|
-
map((applied) => applied.find((t) => t.transactionId === transactionId)),
|
|
2310
|
+
map$1((applied) => applied.find((t) => t.transactionId === transactionId)),
|
|
3205
2311
|
first$1(Boolean)
|
|
3206
2312
|
), successfulTransaction$ = events.pipe(
|
|
3207
|
-
filter((e) => e.type === "accepted"),
|
|
2313
|
+
filter$1((e) => e.type === "accepted"),
|
|
3208
2314
|
first$1((e) => e.outgoing.batchedTransactionIds.includes(transactionId))
|
|
3209
2315
|
), rejectedTransaction$ = events.pipe(
|
|
3210
|
-
filter((e) => e.type === "reverted"),
|
|
2316
|
+
filter$1((e) => e.type === "reverted"),
|
|
3211
2317
|
first$1((e) => e.outgoing.batchedTransactionIds.includes(transactionId))
|
|
3212
2318
|
), appliedTransactionOrError = firstValueFrom(
|
|
3213
2319
|
race([fatalError$, transactionError$, appliedTransaction$])
|
|
@@ -3262,7 +2368,7 @@ const favorites = createFetcherStore({
|
|
|
3262
2368
|
}
|
|
3263
2369
|
};
|
|
3264
2370
|
return nodeStateSource.observable.pipe(
|
|
3265
|
-
filter((nodeState) => !!nodeState),
|
|
2371
|
+
filter$1((nodeState) => !!nodeState),
|
|
3266
2372
|
// Only proceed when connected
|
|
3267
2373
|
shareReplay(1),
|
|
3268
2374
|
switchMap((nodeState) => {
|
|
@@ -3274,55 +2380,21 @@ const favorites = createFetcherStore({
|
|
|
3274
2380
|
payload
|
|
3275
2381
|
)
|
|
3276
2382
|
).pipe(
|
|
3277
|
-
map((response) => ({ isFavorited: response.isFavorited })),
|
|
2383
|
+
map$1((response) => ({ isFavorited: response.isFavorited })),
|
|
3278
2384
|
catchError$1((err) => (console.error("Favorites service connection error", err), of({ isFavorited: !1 })))
|
|
3279
2385
|
);
|
|
3280
2386
|
})
|
|
3281
2387
|
);
|
|
3282
2388
|
}
|
|
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 = {
|
|
2389
|
+
}), getFavoritesState = favorites.getState, resolveFavoritesState = favorites.resolveState, usersStore = defineStore({
|
|
3318
2390
|
name: "UsersStore",
|
|
3319
2391
|
getInitialState: () => ({ users: {} }),
|
|
3320
2392
|
initialize: (context) => {
|
|
3321
2393
|
const subscription = listenForLoadMoreAndFetch(context);
|
|
3322
2394
|
return () => subscription.unsubscribe();
|
|
3323
2395
|
}
|
|
3324
|
-
}, errorHandler
|
|
3325
|
-
map((s) => new Set(Object.keys(s.users))),
|
|
2396
|
+
}), errorHandler = (state) => (error) => state.set("setError", { error }), listenForLoadMoreAndFetch = ({ state, instance }) => state.observable.pipe(
|
|
2397
|
+
map$1((s) => new Set(Object.keys(s.users))),
|
|
3326
2398
|
distinctUntilChanged((curr, next) => curr.size !== next.size ? !1 : Array.from(next).every((i) => curr.has(i))),
|
|
3327
2399
|
startWith$1(/* @__PURE__ */ new Set()),
|
|
3328
2400
|
pairwise$1(),
|
|
@@ -3349,9 +2421,10 @@ const favorites = createFetcherStore({
|
|
|
3349
2421
|
useProjectHostname: !0
|
|
3350
2422
|
}).observable.request({
|
|
3351
2423
|
method: "GET",
|
|
3352
|
-
uri: `/users/${userId}
|
|
2424
|
+
uri: `/users/${userId}`,
|
|
2425
|
+
tag: "users.get"
|
|
3353
2426
|
}).pipe(
|
|
3354
|
-
map((user) => ({
|
|
2427
|
+
map$1((user) => ({
|
|
3355
2428
|
data: [{
|
|
3356
2429
|
sanityUserId: user.sanityUserId,
|
|
3357
2430
|
profile: {
|
|
@@ -3379,13 +2452,14 @@ const favorites = createFetcherStore({
|
|
|
3379
2452
|
);
|
|
3380
2453
|
const scope = userId.startsWith("g") ? "global" : void 0, client = getClient(instance, {
|
|
3381
2454
|
scope,
|
|
3382
|
-
apiVersion: API_VERSION$
|
|
2455
|
+
apiVersion: API_VERSION$6
|
|
3383
2456
|
}), resourceType2 = options.resourceType || "project", resourceId = resourceType2 === "organization" ? options.organizationId : options.projectId;
|
|
3384
2457
|
return resourceId ? client.observable.request({
|
|
3385
2458
|
method: "GET",
|
|
3386
|
-
uri: `access/${resourceType2}/${resourceId}/users/${userId}
|
|
2459
|
+
uri: `access/${resourceType2}/${resourceId}/users/${userId}`,
|
|
2460
|
+
tag: "users.get"
|
|
3387
2461
|
}).pipe(
|
|
3388
|
-
map((response) => "sanityUserId" in response ? {
|
|
2462
|
+
map$1((response) => "sanityUserId" in response ? {
|
|
3389
2463
|
data: [response],
|
|
3390
2464
|
totalCount: 1,
|
|
3391
2465
|
nextCursor: null
|
|
@@ -3395,17 +2469,17 @@ const favorites = createFetcherStore({
|
|
|
3395
2469
|
) : throwError(() => new Error("An organizationId or a projectId is required"));
|
|
3396
2470
|
}
|
|
3397
2471
|
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, {
|
|
2472
|
+
filter$1((i) => typeof i == "string")
|
|
2473
|
+
), 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
2474
|
scope: "global",
|
|
3401
|
-
apiVersion: API_VERSION$
|
|
2475
|
+
apiVersion: API_VERSION$6
|
|
3402
2476
|
}).observable, loadMore$ = state.observable.pipe(
|
|
3403
|
-
map((s) => s.users[group$.key]?.lastLoadMoreRequest),
|
|
2477
|
+
map$1((s) => s.users[group$.key]?.lastLoadMoreRequest),
|
|
3404
2478
|
distinctUntilChanged()
|
|
3405
2479
|
), cursor$ = state.observable.pipe(
|
|
3406
|
-
map((s) => s.users[group$.key]?.nextCursor),
|
|
2480
|
+
map$1((s) => s.users[group$.key]?.nextCursor),
|
|
3407
2481
|
distinctUntilChanged(),
|
|
3408
|
-
filter((cursor) => cursor !== null)
|
|
2482
|
+
filter$1((cursor) => cursor !== null)
|
|
3409
2483
|
);
|
|
3410
2484
|
return combineLatest([resource$, client$, loadMore$]).pipe(
|
|
3411
2485
|
withLatestFrom(cursor$),
|
|
@@ -3413,6 +2487,7 @@ const favorites = createFetcherStore({
|
|
|
3413
2487
|
([[resource, client], cursor]) => client.observable.request({
|
|
3414
2488
|
method: "GET",
|
|
3415
2489
|
uri: `access/${resource.type}/${resource.id}/users`,
|
|
2490
|
+
tag: "users.list",
|
|
3416
2491
|
query: cursor ? { nextCursor: cursor, limit: batchSize.toString() } : { limit: batchSize.toString() }
|
|
3417
2492
|
})
|
|
3418
2493
|
),
|
|
@@ -3422,7 +2497,7 @@ const favorites = createFetcherStore({
|
|
|
3422
2497
|
})
|
|
3423
2498
|
)
|
|
3424
2499
|
)
|
|
3425
|
-
).subscribe({ error: errorHandler
|
|
2500
|
+
).subscribe({ error: errorHandler(state) }), getUsersState = bindActionGlobally(
|
|
3426
2501
|
usersStore,
|
|
3427
2502
|
createStateSourceAction({
|
|
3428
2503
|
selector: createSelector(
|
|
@@ -3441,7 +2516,7 @@ const favorites = createFetcherStore({
|
|
|
3441
2516
|
onSubscribe: ({ instance, state }, options) => {
|
|
3442
2517
|
const subscriptionId = insecureRandomId(), key = getUsersKey(instance, options);
|
|
3443
2518
|
return state.set("addSubscription", addSubscription(subscriptionId, key)), () => {
|
|
3444
|
-
|
|
2519
|
+
setCleanupTimeout(
|
|
3445
2520
|
() => state.set("removeSubscription", removeSubscription(subscriptionId, key)),
|
|
3446
2521
|
USERS_STATE_CLEAR_DELAY
|
|
3447
2522
|
);
|
|
@@ -3465,7 +2540,7 @@ const favorites = createFetcherStore({
|
|
|
3465
2540
|
) : NEVER;
|
|
3466
2541
|
state.set("initializeRequest", initializeRequest(key));
|
|
3467
2542
|
const resolved$ = state.observable.pipe(
|
|
3468
|
-
map(getCurrent),
|
|
2543
|
+
map$1(getCurrent),
|
|
3469
2544
|
first$1((i) => i !== void 0)
|
|
3470
2545
|
);
|
|
3471
2546
|
return firstValueFrom(race([resolved$, aborted$]));
|
|
@@ -3480,7 +2555,7 @@ const favorites = createFetcherStore({
|
|
|
3480
2555
|
throw new Error("No more users available to load for this resource.");
|
|
3481
2556
|
const promise = firstValueFrom(
|
|
3482
2557
|
users.observable.pipe(
|
|
3483
|
-
filter((i) => i !== void 0),
|
|
2558
|
+
filter$1((i) => i !== void 0),
|
|
3484
2559
|
skip(1)
|
|
3485
2560
|
)
|
|
3486
2561
|
), timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -3489,7 +2564,7 @@ const favorites = createFetcherStore({
|
|
|
3489
2564
|
), getUserState = bindActionGlobally(
|
|
3490
2565
|
usersStore,
|
|
3491
2566
|
({ instance }, { userId, ...options }) => getUsersState(instance, { userId, ...options }).observable.pipe(
|
|
3492
|
-
map((res) => res?.data[0]),
|
|
2567
|
+
map$1((res) => res?.data[0]),
|
|
3493
2568
|
distinctUntilChanged((a, b) => a?.profile.updatedAt === b?.profile.updatedAt)
|
|
3494
2569
|
)
|
|
3495
2570
|
), resolveUser = bindActionGlobally(
|
|
@@ -3500,7 +2575,11 @@ const favorites = createFetcherStore({
|
|
|
3500
2575
|
}))?.data[0]
|
|
3501
2576
|
);
|
|
3502
2577
|
function getBifurClient(client, token$) {
|
|
3503
|
-
const bifurVersionedClient = client.withConfig({ apiVersion: "2022-06-30" }), {
|
|
2578
|
+
const bifurVersionedClient = client.withConfig({ apiVersion: "2022-06-30" }), {
|
|
2579
|
+
dataset,
|
|
2580
|
+
url: baseUrl,
|
|
2581
|
+
requestTagPrefix = "sanity.sdk.presence"
|
|
2582
|
+
} = bifurVersionedClient.config(), urlWithTag = `${`${baseUrl.replace(/\/+$/, "")}/socket/${dataset}`.replace(/^http/, "ws")}?tag=${requestTagPrefix}`;
|
|
3504
2583
|
return fromUrl(urlWithTag, { token$ });
|
|
3505
2584
|
}
|
|
3506
2585
|
const handleIncomingMessage = (event) => {
|
|
@@ -3532,7 +2611,7 @@ const handleIncomingMessage = (event) => {
|
|
|
3532
2611
|
throw new Error(`Got unknown presence event: ${JSON.stringify(event)}`);
|
|
3533
2612
|
}
|
|
3534
2613
|
}, createBifurTransport = (options) => {
|
|
3535
|
-
const { client, token$, sessionId } = options, bifur = getBifurClient(client, token$), incomingEvents$ = bifur.listen("presence").pipe(map
|
|
2614
|
+
const { client, token$, sessionId } = options, bifur = getBifurClient(client, token$), incomingEvents$ = bifur.listen("presence").pipe(map(handleIncomingMessage)), dispatchMessage = (message) => {
|
|
3536
2615
|
switch (message.type) {
|
|
3537
2616
|
case "rollCall":
|
|
3538
2617
|
return bifur.request("presence_rollcall", { session: sessionId });
|
|
@@ -3550,7 +2629,7 @@ const handleIncomingMessage = (event) => {
|
|
|
3550
2629
|
}, getInitialState = () => ({
|
|
3551
2630
|
locations: /* @__PURE__ */ new Map(),
|
|
3552
2631
|
users: {}
|
|
3553
|
-
}), presenceStore = {
|
|
2632
|
+
}), presenceStore = defineStore({
|
|
3554
2633
|
name: "presence",
|
|
3555
2634
|
getInitialState,
|
|
3556
2635
|
initialize: (context) => {
|
|
@@ -3587,7 +2666,7 @@ const handleIncomingMessage = (event) => {
|
|
|
3587
2666
|
dispatch({ type: "disconnect" }).subscribe(), subscription.unsubscribe();
|
|
3588
2667
|
};
|
|
3589
2668
|
}
|
|
3590
|
-
}, selectLocations = (state) => state.locations, selectUsers = (state) => state.users, selectPresence = createSelector(
|
|
2669
|
+
}), selectLocations = (state) => state.locations, selectUsers = (state) => state.users, selectPresence = createSelector(
|
|
3591
2670
|
selectLocations,
|
|
3592
2671
|
selectUsers,
|
|
3593
2672
|
(locations, users) => Array.from(locations.entries()).map(([sessionId, { userId, locations: locs }]) => ({
|
|
@@ -3606,7 +2685,7 @@ const handleIncomingMessage = (event) => {
|
|
|
3606
2685
|
selector: (context, _) => selectPresence(context.state),
|
|
3607
2686
|
onSubscribe: (context, _) => {
|
|
3608
2687
|
const subscription = context.state.observable.pipe(
|
|
3609
|
-
map(
|
|
2688
|
+
map$1(
|
|
3610
2689
|
(state) => Array.from(state.locations.values()).map((l) => l.userId).filter((id) => !!id)
|
|
3611
2690
|
),
|
|
3612
2691
|
distinctUntilChanged((a, b) => a.length === b.length && a.every((v, i) => v === b[i]))
|
|
@@ -3619,7 +2698,7 @@ const handleIncomingMessage = (event) => {
|
|
|
3619
2698
|
userId,
|
|
3620
2699
|
resourceType: "project",
|
|
3621
2700
|
projectId: context.key.projectId
|
|
3622
|
-
}).pipe(filter((v) => !!v))
|
|
2701
|
+
}).pipe(filter$1((v) => !!v))
|
|
3623
2702
|
);
|
|
3624
2703
|
return combineLatest(userObservables);
|
|
3625
2704
|
})
|
|
@@ -3636,489 +2715,13 @@ const handleIncomingMessage = (event) => {
|
|
|
3636
2715
|
}
|
|
3637
2716
|
})
|
|
3638
2717
|
);
|
|
3639
|
-
function sortReleases(releases = []) {
|
|
3640
|
-
return [...releases].sort((a, b) => {
|
|
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
|
-
});
|
|
3656
|
-
}
|
|
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
2718
|
function hashString(str) {
|
|
3916
2719
|
let hash = 0;
|
|
3917
2720
|
for (let i = 0; i < str.length; i++)
|
|
3918
2721
|
hash = (hash * 31 + str.charCodeAt(i)) % 2147483647;
|
|
3919
2722
|
return Math.abs(hash).toString(16).padStart(8, "0");
|
|
3920
2723
|
}
|
|
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 = {
|
|
2724
|
+
const PROJECTION_TAG = "projection", PROJECTION_STATE_CLEAR_DELAY = 1e3, STABLE_EMPTY_PROJECTION = {
|
|
4122
2725
|
data: null,
|
|
4123
2726
|
isPending: !1
|
|
4124
2727
|
};
|
|
@@ -4155,7 +2758,7 @@ function processProjectionQuery({
|
|
|
4155
2758
|
}) {
|
|
4156
2759
|
const groupedResults = {};
|
|
4157
2760
|
for (const result of results) {
|
|
4158
|
-
const originalId = getPublishedId(result._id), hash = result.__projectionHash;
|
|
2761
|
+
const originalId = getPublishedId(DocumentId(result._id)), hash = result.__projectionHash;
|
|
4159
2762
|
ids.has(originalId) && (groupedResults[originalId] || (groupedResults[originalId] = {}), groupedResults[originalId][hash] || (groupedResults[originalId][hash] = void 0), groupedResults[originalId][hash] = result);
|
|
4160
2763
|
}
|
|
4161
2764
|
const finalValues = {};
|
|
@@ -4181,7 +2784,7 @@ function processProjectionQuery({
|
|
|
4181
2784
|
function buildStatusQueryIds(documentIds, perspective) {
|
|
4182
2785
|
const ids = [], releaseName = isReleasePerspective(perspective) ? perspective.releaseName : null;
|
|
4183
2786
|
for (const id of documentIds) {
|
|
4184
|
-
const publishedId = getPublishedId
|
|
2787
|
+
const publishedId = getPublishedId(DocumentId(id)), draftId = getDraftId(publishedId);
|
|
4185
2788
|
ids.push(draftId, publishedId), releaseName && ids.push(getVersionId(publishedId, releaseName));
|
|
4186
2789
|
}
|
|
4187
2790
|
return ids;
|
|
@@ -4189,7 +2792,7 @@ function buildStatusQueryIds(documentIds, perspective) {
|
|
|
4189
2792
|
function processStatusQueryResults(results) {
|
|
4190
2793
|
const documentStatuses = {};
|
|
4191
2794
|
for (const result of results) {
|
|
4192
|
-
const id = DocumentId(result._id), updatedAt = result._updatedAt, publishedId = getPublishedId
|
|
2795
|
+
const id = DocumentId(result._id), updatedAt = result._updatedAt, publishedId = getPublishedId(id), statusData = documentStatuses[publishedId] ?? {};
|
|
4193
2796
|
isDraftId(id) ? statusData.lastEditedDraftAt = updatedAt : isVersionId(id) ? statusData.lastEditedVersionAt = updatedAt : isPublishedId(id) && (statusData.lastEditedPublishedAt = updatedAt), documentStatuses[publishedId] = statusData;
|
|
4194
2797
|
}
|
|
4195
2798
|
return documentStatuses;
|
|
@@ -4200,10 +2803,10 @@ const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Arra
|
|
|
4200
2803
|
key: { source, perspective }
|
|
4201
2804
|
}) => {
|
|
4202
2805
|
const documentProjections$ = state.observable.pipe(
|
|
4203
|
-
map((s) => s.documentProjections),
|
|
2806
|
+
map$1((s) => s.documentProjections),
|
|
4204
2807
|
distinctUntilChanged(isEqual)
|
|
4205
2808
|
), activeDocumentIds$ = state.observable.pipe(
|
|
4206
|
-
map(({ subscriptions }) => new Set(Object.keys(subscriptions))),
|
|
2809
|
+
map$1(({ subscriptions }) => new Set(Object.keys(subscriptions))),
|
|
4207
2810
|
distinctUntilChanged(isSetEqual)
|
|
4208
2811
|
), pendingUpdateSubscription = activeDocumentIds$.pipe(
|
|
4209
2812
|
debounceTime(BATCH_DEBOUNCE_TIME),
|
|
@@ -4253,7 +2856,7 @@ const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Arra
|
|
|
4253
2856
|
// temporary guard here until we're ready for everything to be queried via global API in v3
|
|
4254
2857
|
...source && !isDatasetSource(source) ? { source } : {}
|
|
4255
2858
|
})
|
|
4256
|
-
).pipe(switchMap(() => observable)) : observable).pipe(filter((result) => result !== void 0)).subscribe(observer);
|
|
2859
|
+
).pipe(switchMap(() => observable)) : observable).pipe(filter$1((result) => result !== void 0)).subscribe(observer);
|
|
4257
2860
|
return () => {
|
|
4258
2861
|
controller.signal.aborted || controller.abort(), subscription.unsubscribe();
|
|
4259
2862
|
};
|
|
@@ -4275,23 +2878,23 @@ const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Arra
|
|
|
4275
2878
|
// temporary guard here until we're ready for everything to be queried via global API
|
|
4276
2879
|
...source && !isDatasetSource(source) ? { source } : {}
|
|
4277
2880
|
})
|
|
4278
|
-
).pipe(switchMap(() => observable)) : observable).pipe(filter((result) => result !== void 0)).subscribe(observer);
|
|
2881
|
+
).pipe(switchMap(() => observable)) : observable).pipe(filter$1((result) => result !== void 0)).subscribe(observer);
|
|
4279
2882
|
return () => {
|
|
4280
2883
|
subscription.unsubscribe();
|
|
4281
2884
|
};
|
|
4282
2885
|
});
|
|
4283
2886
|
return combineLatest([projectionQuery$, statusQuery$]).pipe(
|
|
4284
|
-
filter(
|
|
2887
|
+
filter$1(
|
|
4285
2888
|
(pair) => pair[0] !== void 0 && pair[1] !== void 0
|
|
4286
2889
|
),
|
|
4287
|
-
map(([projection, status]) => ({
|
|
2890
|
+
map$1(([projection, status]) => ({
|
|
4288
2891
|
data: projection,
|
|
4289
2892
|
ids,
|
|
4290
2893
|
statusResults: status
|
|
4291
2894
|
}))
|
|
4292
2895
|
);
|
|
4293
2896
|
}),
|
|
4294
|
-
map(({ ids, data, statusResults }) => {
|
|
2897
|
+
map$1(({ ids, data, statusResults }) => {
|
|
4295
2898
|
const documentStatuses = processStatusQueryResults(statusResults);
|
|
4296
2899
|
state.set("updateStatuses", (prev) => ({
|
|
4297
2900
|
documentStatuses: {
|
|
@@ -4325,7 +2928,7 @@ const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Arra
|
|
|
4325
2928
|
return new Subscription(() => {
|
|
4326
2929
|
pendingUpdateSubscription.unsubscribe(), queryExecutionSubscription.unsubscribe();
|
|
4327
2930
|
});
|
|
4328
|
-
}, projectionStore = {
|
|
2931
|
+
}, projectionStore = defineStore({
|
|
4329
2932
|
name: "Projection",
|
|
4330
2933
|
getInitialState() {
|
|
4331
2934
|
return {
|
|
@@ -4339,7 +2942,7 @@ const BATCH_DEBOUNCE_TIME = 50, isSetEqual = (a, b) => a.size === b.size && Arra
|
|
|
4339
2942
|
const batchSubscription = subscribeToStateAndFetchBatches(context);
|
|
4340
2943
|
return () => batchSubscription.unsubscribe();
|
|
4341
2944
|
}
|
|
4342
|
-
};
|
|
2945
|
+
});
|
|
4343
2946
|
function getProjectionState(...args) {
|
|
4344
2947
|
return _getProjectionState(...args);
|
|
4345
2948
|
}
|
|
@@ -4347,11 +2950,11 @@ const _getProjectionState = bindActionBySourceAndPerspective(
|
|
|
4347
2950
|
projectionStore,
|
|
4348
2951
|
createStateSourceAction({
|
|
4349
2952
|
selector: ({ state }, options) => {
|
|
4350
|
-
const documentId = getPublishedId
|
|
2953
|
+
const documentId = getPublishedId(DocumentId(options.documentId)), projectionHash = hashString(options.projection);
|
|
4351
2954
|
return state.values[documentId]?.[projectionHash] ?? STABLE_EMPTY_PROJECTION;
|
|
4352
2955
|
},
|
|
4353
2956
|
onSubscribe: ({ state }, options) => {
|
|
4354
|
-
const { projection, ...docHandle } = options, subscriptionId = insecureRandomId(), documentId = getPublishedId
|
|
2957
|
+
const { projection, ...docHandle } = options, subscriptionId = insecureRandomId(), documentId = getPublishedId(DocumentId(docHandle.documentId)), validProjection = validateProjection(projection), projectionHash = hashString(validProjection);
|
|
4355
2958
|
return state.set("addSubscription", (prev) => ({
|
|
4356
2959
|
documentProjections: {
|
|
4357
2960
|
...prev.documentProjections,
|
|
@@ -4371,7 +2974,7 @@ const _getProjectionState = bindActionBySourceAndPerspective(
|
|
|
4371
2974
|
}
|
|
4372
2975
|
}
|
|
4373
2976
|
})), () => {
|
|
4374
|
-
|
|
2977
|
+
setCleanupTimeout(() => {
|
|
4375
2978
|
state.set("removeSubscription", (prev) => {
|
|
4376
2979
|
const documentSubscriptionsForHash = omit(
|
|
4377
2980
|
prev.subscriptions[documentId]?.[projectionHash],
|
|
@@ -4400,6 +3003,20 @@ const _getProjectionState = bindActionBySourceAndPerspective(
|
|
|
4400
3003
|
}
|
|
4401
3004
|
})
|
|
4402
3005
|
);
|
|
3006
|
+
function getPreviewState(instance, options) {
|
|
3007
|
+
const projectionState = getProjectionState(instance, {
|
|
3008
|
+
...options,
|
|
3009
|
+
projection: PREVIEW_PROJECTION
|
|
3010
|
+
}), transformResult = (current) => !current || current.data === null ? { data: null, isPending: current?.isPending ?? !1 } : {
|
|
3011
|
+
data: transformProjectionToPreview(instance, current.data, options.source),
|
|
3012
|
+
isPending: current.isPending
|
|
3013
|
+
};
|
|
3014
|
+
return {
|
|
3015
|
+
getCurrent: () => transformResult(projectionState.getCurrent()),
|
|
3016
|
+
subscribe: (callback) => projectionState.subscribe(callback),
|
|
3017
|
+
observable: projectionState.observable.pipe(map$1(transformResult))
|
|
3018
|
+
};
|
|
3019
|
+
}
|
|
4403
3020
|
function resolveProjection(...args) {
|
|
4404
3021
|
return _resolveProjection(...args);
|
|
4405
3022
|
}
|
|
@@ -4407,10 +3024,21 @@ const _resolveProjection = bindActionBySourceAndPerspective(
|
|
|
4407
3024
|
projectionStore,
|
|
4408
3025
|
({ instance }, options) => firstValueFrom(
|
|
4409
3026
|
getProjectionState(instance, options).observable.pipe(
|
|
4410
|
-
filter((state) => !!state?.data)
|
|
3027
|
+
filter$1((state) => !!state?.data)
|
|
4411
3028
|
)
|
|
4412
3029
|
)
|
|
4413
|
-
)
|
|
3030
|
+
);
|
|
3031
|
+
async function resolvePreview(instance, options) {
|
|
3032
|
+
const projectionResult = await resolveProjection(instance, {
|
|
3033
|
+
...options,
|
|
3034
|
+
projection: PREVIEW_PROJECTION
|
|
3035
|
+
});
|
|
3036
|
+
return projectionResult.data ? {
|
|
3037
|
+
data: transformProjectionToPreview(instance, projectionResult.data, options.source),
|
|
3038
|
+
isPending: projectionResult.isPending
|
|
3039
|
+
} : { data: null, isPending: projectionResult.isPending };
|
|
3040
|
+
}
|
|
3041
|
+
const API_VERSION = "v2025-02-19", projects = createFetcherStore({
|
|
4414
3042
|
name: "Projects",
|
|
4415
3043
|
getKey: (_instance, options) => {
|
|
4416
3044
|
const orgKey = options?.organizationId ? `:org:${options.organizationId}` : "", membersKey = options?.includeMembers === !1 ? ":no-members" : "";
|
|
@@ -4430,29 +3058,7 @@ const _resolveProjection = bindActionBySourceAndPerspective(
|
|
|
4430
3058
|
});
|
|
4431
3059
|
})
|
|
4432
3060
|
)
|
|
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
|
-
}
|
|
3061
|
+
}), getProjectsState = projects.getState, resolveProjects = projects.resolveState;
|
|
4456
3062
|
function defineIntent(intent) {
|
|
4457
3063
|
if (!intent.id)
|
|
4458
3064
|
throw new Error("Intent must have an id");
|
|
@@ -4511,11 +3117,10 @@ function getCorsErrorProjectId(error) {
|
|
|
4511
3117
|
const projMatch = (error.message || "").match(/manage\/project\/([^/?#]+)/);
|
|
4512
3118
|
return projMatch ? projMatch[1] : null;
|
|
4513
3119
|
}
|
|
4514
|
-
var version = "2.8.0";
|
|
4515
|
-
const CORE_SDK_VERSION = getEnv("PKG_VERSION") || `${version}-development`;
|
|
4516
3120
|
export {
|
|
4517
3121
|
AuthStateType,
|
|
4518
3122
|
CORE_SDK_VERSION,
|
|
3123
|
+
PREVIEW_PROJECTION,
|
|
4519
3124
|
agentGenerate,
|
|
4520
3125
|
agentPatch,
|
|
4521
3126
|
agentPrompt,
|
|
@@ -4601,6 +3206,7 @@ export {
|
|
|
4601
3206
|
slicePath2 as slicePath,
|
|
4602
3207
|
stringifyPath2 as stringifyPath,
|
|
4603
3208
|
subscribeDocumentEvents,
|
|
3209
|
+
transformProjectionToPreview,
|
|
4604
3210
|
unpublishDocument
|
|
4605
3211
|
};
|
|
4606
3212
|
//# sourceMappingURL=index.js.map
|