@sanity/sdk 3.0.0-rc.2 → 3.1.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.
Files changed (102) hide show
  1. package/dist/_exports/_internal.d.ts +25 -3
  2. package/dist/_exports/_internal.d.ts.map +1 -1
  3. package/dist/_exports/_internal.js +127 -9
  4. package/dist/_exports/_internal.js.map +1 -1
  5. package/dist/_exports/agent.d.ts +1 -1
  6. package/dist/_exports/agent.js +1 -1
  7. package/dist/_exports/comlink.d.ts +1 -1
  8. package/dist/_exports/comlink.js +2 -3
  9. package/dist/_exports/comlink.js.map +1 -1
  10. package/dist/{authStore-DKFX8fn7.d.ts → authStore-C-OEkGaM.d.ts} +30 -44
  11. package/dist/authStore-C-OEkGaM.d.ts.map +1 -0
  12. package/dist/{authStore-CtE9bLHW.js → clientStore-gUALQ0qW.js} +269 -11
  13. package/dist/{authStore-CtE9bLHW.js.map → clientStore-gUALQ0qW.js.map} +1 -1
  14. package/dist/{createSanityInstance-DUI1bGIg.d.ts → createSanityInstance-DCePpBYW.d.ts} +2 -2
  15. package/dist/{createSanityInstance-DUI1bGIg.d.ts.map → createSanityInstance-DCePpBYW.d.ts.map} +1 -1
  16. package/dist/{getNodeState-CR3__B2D.js → getNodeState-E0hjqFOo.js} +2 -3
  17. package/dist/{getNodeState-CR3__B2D.js.map → getNodeState-E0hjqFOo.js.map} +1 -1
  18. package/dist/index.d.ts +3 -3
  19. package/dist/index.js +168 -176
  20. package/dist/index.js.map +1 -1
  21. package/dist/{createStateSourceAction-BOKtqFNm.js → object-BwynGPRZ.js} +87 -3
  22. package/dist/object-BwynGPRZ.js.map +1 -0
  23. package/dist/{queryStore-DPf9sN3V.js → version-C90rNWaX.js} +48 -16
  24. package/dist/version-C90rNWaX.js.map +1 -0
  25. package/package.json +4 -4
  26. package/src/_exports/_internal.ts +1 -0
  27. package/src/_exports/index.ts +7 -4
  28. package/src/access/checkPermissions.test.ts +1 -1
  29. package/src/access/checkPermissions.ts +1 -1
  30. package/src/applications/applications.test.ts +4 -4
  31. package/src/applications/applications.ts +4 -4
  32. package/src/auth/handleAuthCallback.test.ts +2 -2
  33. package/src/auth/handleAuthCallback.ts +1 -1
  34. package/src/auth/logout.test.ts +1 -1
  35. package/src/auth/logout.ts +1 -1
  36. package/src/auth/refreshStampedToken.ts +1 -1
  37. package/src/auth/studioModeAuth.test.ts +1 -1
  38. package/src/auth/studioModeAuth.ts +1 -1
  39. package/src/auth/subscribeToStateAndFetchCurrentUser.test.ts +2 -2
  40. package/src/auth/subscribeToStateAndFetchCurrentUser.ts +1 -1
  41. package/src/comments/addonDatasetStore.test.ts +2 -2
  42. package/src/comments/addonDatasetStore.ts +2 -2
  43. package/src/comments/commentActions.ts +6 -5
  44. package/src/comments/commentsStore.ts +4 -4
  45. package/src/datasets/datasets.test.ts +44 -9
  46. package/src/datasets/datasets.ts +24 -23
  47. package/src/document/applyDocumentActions.ts +2 -6
  48. package/src/document/documentConstants.ts +9 -0
  49. package/src/document/documentStore.concurrency.test.ts +2 -1
  50. package/src/document/documentStore.test.ts +87 -17
  51. package/src/document/documentStore.ts +5 -5
  52. package/src/document/permissions.ts +2 -1
  53. package/src/document/processActions.test.ts +2 -1
  54. package/src/document/processMutations.ts +3 -2
  55. package/src/document/reducers.test.ts +224 -0
  56. package/src/document/reducers.ts +110 -27
  57. package/src/favorites/favorites.test.ts +64 -24
  58. package/src/favorites/favorites.ts +73 -22
  59. package/src/installations/installations.test.ts +2 -2
  60. package/src/installations/installations.ts +2 -2
  61. package/src/organization/organization.test.ts +2 -2
  62. package/src/organization/organization.ts +1 -1
  63. package/src/organizations/organizations.test.ts +2 -2
  64. package/src/organizations/organizations.ts +1 -1
  65. package/src/presence/presenceStore.test.ts +15 -22
  66. package/src/presence/presenceStore.ts +3 -2
  67. package/src/project/project.test.ts +3 -3
  68. package/src/project/project.ts +1 -1
  69. package/src/projection/getProjectionState.test.ts +6 -4
  70. package/src/projection/getProjectionState.ts +2 -2
  71. package/src/projects/projects.test.ts +2 -2
  72. package/src/projects/projects.ts +1 -1
  73. package/src/query/queryStore.ts +3 -3
  74. package/src/store/createSanityInstance.test.ts +1 -1
  75. package/src/store/createSanityInstance.ts +4 -4
  76. package/src/store/createStoreInstance.test.ts +0 -5
  77. package/src/store/fetcherStore.test.ts +23 -1
  78. package/src/store/fetcherStore.ts +3 -3
  79. package/src/telemetry/telemetryManager.test.ts +1 -1
  80. package/src/telemetry/telemetryManager.ts +2 -2
  81. package/src/users/usersStore.test.ts +1 -1
  82. package/src/users/usersStore.ts +5 -5
  83. package/src/utils/ids.test.ts +40 -15
  84. package/src/utils/ids.ts +47 -2
  85. package/dist/authStore-DKFX8fn7.d.ts.map +0 -1
  86. package/dist/clientStore-BtE2-q2i.js +0 -90
  87. package/dist/clientStore-BtE2-q2i.js.map +0 -1
  88. package/dist/createStateSourceAction-BOKtqFNm.js.map +0 -1
  89. package/dist/getEnv-D5RGkQLu.js +0 -8
  90. package/dist/getEnv-D5RGkQLu.js.map +0 -1
  91. package/dist/logger-DAtJb5RQ.js +0 -173
  92. package/dist/logger-DAtJb5RQ.js.map +0 -1
  93. package/dist/object-CxXlSVg7.js +0 -83
  94. package/dist/object-CxXlSVg7.js.map +0 -1
  95. package/dist/queryStore-DPf9sN3V.js.map +0 -1
  96. package/dist/rolldown-runtime-vyAXikos.js +0 -9
  97. package/dist/telemetryManager-Dq_qCkeI.js +0 -127
  98. package/dist/telemetryManager-Dq_qCkeI.js.map +0 -1
  99. package/dist/version-BChjsi4u.js +0 -9
  100. package/dist/version-BChjsi4u.js.map +0 -1
  101. package/src/utils/createFetcherStore.test.ts +0 -171
  102. package/src/utils/createFetcherStore.ts +0 -284
@@ -1,5 +1,5 @@
1
- import { m as SanityConfig, s as DocumentResource, t as SanityInstance } from "../createSanityInstance-DUI1bGIg.js";
2
- import { B as getQueryKey, Ci as defineMutation, H as parseQueryKey, Si as defineFetcher, _i as Fetcher, _r as getCommentsOptionsKey, bi as MutationDefinition, gi as CacheWriter, hi as CacheTag, nt as PreviewQueryResult, rt as PreviewValue, vi as FetcherDefinition, xi as MutationResult, xt as GetUsersOptions, yi as FetcherSnapshot, yr as parseCommentsOptionsKey } from "../authStore-DKFX8fn7.js";
1
+ import { m as SanityConfig, s as DocumentResource, t as SanityInstance } from "../createSanityInstance-DCePpBYW.js";
2
+ import { B as parseQueryKey, R as getQueryKey, Si as defineMutation, _i as FetcherDefinition, bi as MutationResult, et as PreviewQueryResult, gi as Fetcher, gr as getCommentsOptionsKey, hi as CacheWriter, mi as CacheTag, tt as PreviewValue, vi as FetcherSnapshot, vr as parseCommentsOptionsKey, xi as defineFetcher, yi as MutationDefinition, yt as GetUsersOptions } from "../authStore-C-OEkGaM.js";
3
3
  import { ClientError, SanityClient } from "@sanity/client";
4
4
  import { Observable } from "rxjs";
5
5
  import { CurrentUser } from "@sanity/types";
@@ -145,6 +145,28 @@ declare const parseUsersKey: (key: string) => {
145
145
  * @internal
146
146
  */
147
147
  declare function createGroqSearchFilter(query: string): string;
148
+ /**
149
+ * Generates a random ID of the given length from the alphabet `[a-zA-Z0-9]`, the same shape
150
+ * `@sanity/client` and Sanity Studio use for short IDs such as release IDs.
151
+ *
152
+ * Ported from `@sanity/client`'s `generateReleaseId`, which uses rejection sampling to keep
153
+ * the output unbiased. Uses `crypto.getRandomValues`, which unlike `crypto.randomUUID` is
154
+ * also available on insecure origins (plain http).
155
+ *
156
+ * @internal
157
+ */
158
+ declare function randomId(length?: number): string;
159
+ /**
160
+ * Generates a random v4 UUID.
161
+ *
162
+ * Prefers the native `crypto.randomUUID`, which is only available in secure contexts
163
+ * (https, localhost). Falls back to deriving the UUID from `crypto.getRandomValues`,
164
+ * which has no such restriction, so ID generation also works when an app is served over
165
+ * plain http, e.g. when testing from a phone on a local network.
166
+ *
167
+ * @internal
168
+ */
169
+ declare function randomUuid(): string;
148
170
  /**
149
171
  * Creates a shallow copy containing only the provided properties.
150
172
  *
@@ -159,5 +181,5 @@ declare function pickProperties<T extends object, K extends keyof T>(value: T, k
159
181
  * @internal
160
182
  */
161
183
  declare function isDeepEqual<T>(left: T, right: T): boolean;
162
- export { type ApiErrorBody, type CacheTag, type CacheWriter, type Fetcher, type FetcherDefinition, type FetcherSnapshot, type MutationDefinition, type MutationResult, PREVIEW_PROJECTION, createGroqSearchFilter, defineFetcher, defineMutation, getClientErrorApiBody, getClientErrorApiDescription, getClientErrorApiType, getCommentsOptionsKey, getQueryKey, getTelemetryManager, getUsersKey, initTelemetry, isDeepEqual, isProjectUserNotFoundClientError, isStudioConfig, parseCommentsOptionsKey, parseQueryKey, parseUsersKey, pickProperties, trackHookMounted, transformProjectionToPreview };
184
+ export { type ApiErrorBody, type CacheTag, type CacheWriter, type Fetcher, type FetcherDefinition, type FetcherSnapshot, type MutationDefinition, type MutationResult, PREVIEW_PROJECTION, createGroqSearchFilter, defineFetcher, defineMutation, getClientErrorApiBody, getClientErrorApiDescription, getClientErrorApiType, getCommentsOptionsKey, getQueryKey, getTelemetryManager, getUsersKey, initTelemetry, isDeepEqual, isProjectUserNotFoundClientError, isStudioConfig, parseCommentsOptionsKey, parseQueryKey, parseUsersKey, pickProperties, randomId, randomUuid, trackHookMounted, transformProjectionToPreview };
163
185
  //# sourceMappingURL=_internal.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"_internal.d.ts","names":[],"sources":["../../src/auth/authMode.ts","../../src/auth/utils.ts","../../src/preview/previewConstants.ts","../../src/preview/previewProjectionUtils.ts","../../src/telemetry/telemetryManager.ts","../../src/telemetry/initTelemetry.ts","../../src/users/reducers.ts","../../src/utils/createGroqSearchFilter.ts","../../src/utils/object.ts"],"mappings":";;;;;;;;;;iBAsCgB,eAAe,QAAQ;;KC0I3B;EACV;IAAS;IAAe;;EACxB;EACA;EACA;;;iBAIc,sBAAsB,OAAO,cAAc;;iBAM3C,sBAAsB,OAAO;;iBAM7B,6BAA6B,OAAO;;iBAMpC,iCAAiC,OAAO;;;;;;;cCpL3C;;;;;;;;;;iBCiDG,6BACd,UAAU,gBACV,kBAAkB,oBAClB,WAAW,mBACV;;;;;;;;;;;;UC3Cc;;;;;;;EAOf,gBAAgB;;EAGhB,kBAAkB;IAAO;IAAmB;IAAqB;;;EAGjE,iBAAiB;;EAGjB,SAAS,mBAAmB;;EAG5B;;EAGA;;WAGS,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCXN,cAAc,UAAU,gBAAgB;;;;;;;iBAoIxC,oBAAoB,UAAU,iBAAiB;;;;;;;;iBAW/C,iBAAiB,UAAU,gBAAgB;;cCvL9C,cACX,UAAU,kBACV,cAAA,gBAAA,WAAA,WAAA,WAMG;;cAWQ,gBACX;EAEA;EACA;EACA;EACA;EACA;;;;;;;;;;;;;;;iBCYc,uBAAuB;;;;;;iBCNvB,eAAe,kBAAkB,gBAAgB,GAC/D,OAAO,GACP,eAAe,MACd,KAAK,GAAG;;;;;;;;iBA2DK,YAAY,GAAG,MAAM,GAAG,OAAO"}
1
+ {"version":3,"file":"_internal.d.ts","names":[],"sources":["../../src/auth/authMode.ts","../../src/auth/utils.ts","../../src/preview/previewConstants.ts","../../src/preview/previewProjectionUtils.ts","../../src/telemetry/telemetryManager.ts","../../src/telemetry/initTelemetry.ts","../../src/users/reducers.ts","../../src/utils/createGroqSearchFilter.ts","../../src/utils/ids.ts","../../src/utils/object.ts"],"mappings":";;;;;;;;;;iBAsCgB,eAAe,QAAQ;;KC0I3B;EACV;IAAS;IAAe;;EACxB;EACA;EACA;;;iBAIc,sBAAsB,OAAO,cAAc;;iBAM3C,sBAAsB,OAAO;;iBAM7B,6BAA6B,OAAO;;iBAMpC,iCAAiC,OAAO;;;;;;;cCpL3C;;;;;;;;;;iBCiDG,6BACd,UAAU,gBACV,kBAAkB,oBAClB,WAAW,mBACV;;;;;;;;;;;;UC3Cc;;;;;;;EAOf,gBAAgB;;EAGhB,kBAAkB;IAAO;IAAmB;IAAqB;;;EAGjE,iBAAiB;;EAGjB,SAAS,mBAAmB;;EAG5B;;EAGA;;WAGS,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;iBCXN,cAAc,UAAU,gBAAgB;;;;;;;iBAoIxC,oBAAoB,UAAU,iBAAiB;;;;;;;;iBAW/C,iBAAiB,UAAU,gBAAgB;;cCvL9C,cACX,UAAU,kBACV,cAAA,gBAAA,WAAA,WAAA,WAMG;;cAWQ,gBACX;EAEA;EACA;EACA;EACA;EACA;;;;;;;;;;;;;;;iBCYc,uBAAuB;;;;;;;;;;;iBChCvB,SAAS;;;;;;;;;;;iBAsBT;;;;;;iBCIA,eAAe,kBAAkB,gBAAgB,GAC/D,OAAO,GACP,eAAe,MACd,KAAK,GAAG;;;;;;;;iBA2DK,YAAY,GAAG,MAAM,GAAG,OAAO"}
@@ -1,10 +1,9 @@
1
- import { C as parseCommentsOptionsKey, U as defineFetcher, W as defineMutation, f as parseUsersKey, r as parseQueryKey, t as getQueryKey, u as getUsersKey, x as getCommentsOptionsKey } from "../queryStore-DPf9sN3V.js";
2
- import { n as createLogger } from "../logger-DAtJb5RQ.js";
3
- import { g as getClientErrorApiType, h as getClientErrorApiDescription, m as getClientErrorApiBody, x as isStudioConfig, y as isProjectUserNotFoundClientError } from "../authStore-CtE9bLHW.js";
4
- import { i as pickProperties, n as isObject, t as isDeepEqual } from "../object-CxXlSVg7.js";
5
- import { n as getClient } from "../clientStore-BtE2-q2i.js";
1
+ import { C as isStudioConfig, O as createLogger, _ as getClientErrorApiDescription, g as getClientErrorApiBody, k as __exportAll, n as getClient, v as getClientErrorApiType, x as isProjectUserNotFoundClientError } from "../clientStore-gUALQ0qW.js";
2
+ import { i as pickProperties, n as isObject, t as isDeepEqual } from "../object-BwynGPRZ.js";
3
+ import { G as defineMutation, K as randomId, S as getCommentsOptionsKey, W as defineFetcher, d as getUsersKey, i as parseQueryKey, n as getQueryKey, p as parseUsersKey, q as randomUuid, t as CORE_SDK_VERSION, w as parseCommentsOptionsKey } from "../version-C90rNWaX.js";
6
4
  import "@sanity/client";
7
5
  import { createImageUrlBuilder } from "@sanity/image-url";
6
+ import { createBatchedStore, defineEvent } from "@sanity/telemetry";
8
7
  /**
9
8
  * The fields to check for a title.
10
9
  * The order of the items in the array defines the priority.
@@ -150,6 +149,125 @@ function getTelemetryEnvironment() {
150
149
  }
151
150
  return typeof process < "u" && process.env?.NODE_ENV === "development" ? "development" : null;
152
151
  }
152
+ /** @internal */
153
+ const SDKSessionStarted = defineEvent({
154
+ name: "SDK Session Started",
155
+ version: 1,
156
+ description: "SDK instance created (environment is recorded in the event context)"
157
+ }), SDKHookMounted = defineEvent({
158
+ name: "SDK Hook Mounted",
159
+ version: 1,
160
+ description: "An SDK hook was mounted for the first time in this session"
161
+ }), SDKSessionEnded = defineEvent({
162
+ name: "SDK Session Ended",
163
+ version: 1,
164
+ description: "SDK instance disposed (environment is recorded in the event context)"
165
+ }), SDKError = defineEvent({
166
+ name: "SDK Error",
167
+ version: 1,
168
+ description: "Runtime error caught in the SDK"
169
+ });
170
+ var telemetryManager_exports = /* @__PURE__ */ __exportAll({ createTelemetryManager: () => createTelemetryManager });
171
+ const log = createLogger("telemetry");
172
+ /**
173
+ * Creates a telemetry manager for a single SDK instance session.
174
+ *
175
+ * The manager initializes a `createBatchedStore` from `@sanity/telemetry`,
176
+ * caches the consent check for the lifetime of the session, and provides
177
+ * typed methods for each SDK telemetry event.
178
+ *
179
+ * @internal
180
+ */
181
+ function createTelemetryManager(options) {
182
+ let { sessionId, getClient, projectId, environment } = options, startedAt = Date.now(), emittedHooks = /* @__PURE__ */ new Set(), cachedConsent = null, resolveConsent = async () => {
183
+ if (cachedConsent) return cachedConsent;
184
+ try {
185
+ cachedConsent = await getClient().request({
186
+ url: "/intake/telemetry-status",
187
+ tag: "telemetry-consent.sdk"
188
+ });
189
+ } catch {
190
+ cachedConsent = { status: "undetermined" };
191
+ }
192
+ return cachedConsent;
193
+ }, enrichBatch = (batch) => batch.map((event) => {
194
+ let existing = "context" in event ? event.context : void 0;
195
+ return {
196
+ ...event,
197
+ context: {
198
+ ...existing,
199
+ version: CORE_SDK_VERSION,
200
+ environment,
201
+ origin: typeof window < "u" ? window.location.origin : "node"
202
+ }
203
+ };
204
+ }), sendEvents = async (batch) => {
205
+ let client = getClient();
206
+ return log.debug("sending event batch", {
207
+ batchSize: batch.length,
208
+ environment
209
+ }), client.request({
210
+ url: "/intake/batch",
211
+ method: "POST",
212
+ body: {
213
+ projectId,
214
+ batch: enrichBatch(batch)
215
+ },
216
+ tag: "telemetry.batch"
217
+ });
218
+ }, store = createBatchedStore(sessionId, {
219
+ flushInterval: 3e4,
220
+ resolveConsent,
221
+ sendEvents
222
+ }), logger = store.logger;
223
+ return {
224
+ async checkConsent() {
225
+ let { status } = await resolveConsent();
226
+ return status === "granted";
227
+ },
228
+ logSessionStarted(data) {
229
+ log.debug("event: SDK Session Started", {
230
+ projectId: data.projectId,
231
+ perspective: data.perspective,
232
+ authMethod: data.authMethod,
233
+ version: CORE_SDK_VERSION,
234
+ environment
235
+ }), logger.log(SDKSessionStarted, {
236
+ version: CORE_SDK_VERSION,
237
+ ...data
238
+ });
239
+ },
240
+ logHookFirstUsed(hookName) {
241
+ emittedHooks.has(hookName) || (emittedHooks.add(hookName), log.debug("event: SDK Hook Mounted", { hookName }), logger.log(SDKHookMounted, { hookName }));
242
+ },
243
+ logError(errorType, hookName) {
244
+ log.debug("event: SDK Error", {
245
+ errorType,
246
+ hookName
247
+ }), logger.log(SDKError, {
248
+ errorType,
249
+ hookName
250
+ });
251
+ },
252
+ endSession() {
253
+ let durationSeconds = Math.round((Date.now() - startedAt) / 1e3);
254
+ log.debug("event: SDK Session Ended", {
255
+ durationSeconds,
256
+ hooksUsed: [...emittedHooks],
257
+ environment
258
+ }), logger.log(SDKSessionEnded, {
259
+ durationSeconds,
260
+ hooksUsed: [...emittedHooks]
261
+ }), store.flush().catch(() => {}), store.end();
262
+ },
263
+ dispose() {
264
+ store.end();
265
+ },
266
+ get hooksUsed() {
267
+ return emittedHooks;
268
+ }
269
+ };
270
+ }
153
271
  const logger = createLogger("telemetry"), telemetryManagers = /* @__PURE__ */ new WeakMap(), pendingHooks = /* @__PURE__ */ new WeakMap(), initInFlight = /* @__PURE__ */ new WeakSet();
154
272
  /**
155
273
  * Initializes telemetry for a SDK instance if the runtime environment
@@ -190,9 +308,9 @@ function initTelemetry(instance, projectId) {
190
308
  projectId,
191
309
  environment
192
310
  }), Promise.all([
193
- import("../telemetryManager-Dq_qCkeI.js").then((n) => n.t),
194
- import("../clientStore-BtE2-q2i.js").then((n) => n.t),
195
- import("../authStore-CtE9bLHW.js").then((n) => n.n)
311
+ Promise.resolve().then(() => telemetryManager_exports),
312
+ import("../clientStore-gUALQ0qW.js").then((n) => n.t),
313
+ import("../clientStore-gUALQ0qW.js").then((n) => n.a)
196
314
  ]).then(async ([{ createTelemetryManager }, { getClient }, { getTokenState }]) => {
197
315
  if (instance.isDisposed()) {
198
316
  initInFlight.delete(instance), logger.debug("telemetry skipped: instance disposed before imports resolved");
@@ -327,6 +445,6 @@ function createGroqSearchFilter(query) {
327
445
  let tokens = trimmedQuery.match(TOKEN_REGEX) ?? [], reversedIndex = [...tokens].reverse().findIndex((token) => !isNegationToken(token) && !isExactMatchToken(token)), finalIncrementalTokenIndex = reversedIndex === -1 ? -1 : tokens.length - 1 - reversedIndex, finalIncrementalToken = tokens[finalIncrementalTokenIndex], processedTokens = [...tokens];
328
446
  return finalIncrementalToken !== void 0 && !isPrefixToken(finalIncrementalToken) && processedTokens.splice(finalIncrementalTokenIndex, 1, `${finalIncrementalToken}*`), `[@] match text::query("${processedTokens.join(" ").replace(/"/g, "\\\"")}")`;
329
447
  }
330
- export { PREVIEW_PROJECTION, createGroqSearchFilter, defineFetcher, defineMutation, getClientErrorApiBody, getClientErrorApiDescription, getClientErrorApiType, getCommentsOptionsKey, getQueryKey, getTelemetryManager, getUsersKey, initTelemetry, isDeepEqual, isProjectUserNotFoundClientError, isStudioConfig, parseCommentsOptionsKey, parseQueryKey, parseUsersKey, pickProperties, trackHookMounted, transformProjectionToPreview };
448
+ export { PREVIEW_PROJECTION, createGroqSearchFilter, defineFetcher, defineMutation, getClientErrorApiBody, getClientErrorApiDescription, getClientErrorApiType, getCommentsOptionsKey, getQueryKey, getTelemetryManager, getUsersKey, initTelemetry, isDeepEqual, isProjectUserNotFoundClientError, isStudioConfig, parseCommentsOptionsKey, parseQueryKey, parseUsersKey, pickProperties, randomId, randomUuid, trackHookMounted, transformProjectionToPreview };
331
449
 
332
450
  //# sourceMappingURL=_internal.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"_internal.js","names":[],"sources":["../../src/preview/previewConstants.ts","../../src/preview/previewProjectionUtils.ts","../../src/telemetry/environment.ts","../../src/telemetry/initTelemetry.ts","../../src/utils/createGroqSearchFilter.ts"],"sourcesContent":["/**\n * The fields to check for a title.\n * The order of the items in the array defines the priority.\n *\n * @internal\n */\nexport const TITLE_CANDIDATES = ['title', 'name', 'label', 'heading', 'header', 'caption']\n\n/**\n * The fields to check for a subtitle.\n * The order of the items in the array defines the priority.\n *\n * @internal\n */\nexport const SUBTITLE_CANDIDATES = ['description', 'subtitle', ...TITLE_CANDIDATES]\n\n/**\n * Generates a GROQ projection for preview data without requiring a schema.\n * Uses common field names to make educated guesses about which fields to use.\n *\n * @internal\n */\nexport const PREVIEW_PROJECTION = `{\n // Get all potential title fields\n \"titleCandidates\": {\n ${TITLE_CANDIDATES.map((field) => `\"${field}\": ${field}`).join(',\\n ')}\n },\n // Get all potential subtitle fields\n \"subtitleCandidates\": {\n ${SUBTITLE_CANDIDATES.map((field) => `\"${field}\": ${field}`).join(',\\n ')}\n },\n \"media\": coalesce(\n select(\n defined(asset) => {\"type\": \"image-asset\", \"_ref\": asset._ref},\n defined(image.asset) => {\"type\": \"image-asset\", \"_ref\": image.asset._ref},\n defined(mainImage.asset) => {\"type\": \"image-asset\", \"_ref\": mainImage.asset._ref},\n null\n )\n ),\n _type,\n _id,\n _updatedAt\n}`\n","import {type SanityClient} from '@sanity/client'\nimport {createImageUrlBuilder} from '@sanity/image-url'\n\nimport {getClient} from '../client/clientStore'\nimport {type DocumentResource} from '../config/sanityConfig'\nimport {type SanityInstance} from '../store/createSanityInstance'\nimport {isObject} from '../utils/object'\nimport {SUBTITLE_CANDIDATES, TITLE_CANDIDATES} from './previewConstants'\nimport {type PreviewQueryResult, type PreviewValue} from './types'\n\nconst API_VERSION = 'v2025-05-06'\n\n/**\n * Checks if the provided value has `_ref` property that is a string and starts with `image-`\n */\nfunction hasImageRef<T>(value: unknown): value is T & {_ref: string} {\n return isObject(value) && '_ref' in value && typeof (value as {_ref: unknown})._ref === 'string'\n}\n\n/**\n * Normalizes a media asset to a preview value.\n * Adds a url to a media asset reference using `@sanity/image-url`.\n *\n * @internal\n */\nexport function normalizeMedia(media: unknown, client: SanityClient): PreviewValue['media'] {\n if (!media) return null\n if (!hasImageRef(media)) return null\n\n const builder = createImageUrlBuilder(client)\n const url = builder.image({_ref: media._ref}).url()\n\n return {\n type: 'image-asset',\n _ref: media._ref,\n url,\n }\n}\n\n/**\n * Finds a single field value from a set of candidates based on a priority list of field names.\n * Returns the first non-empty string value found from the candidates matching the priority list order.\n *\n * @internal\n */\nfunction findFirstDefined(\n fieldsToSearch: string[],\n candidates: Record<string, unknown>,\n exclude?: unknown,\n): string | undefined {\n if (!candidates) return undefined\n\n for (const field of fieldsToSearch) {\n const value = candidates[field]\n if (typeof value === 'string' && value.trim() !== '' && value !== exclude) {\n return value\n }\n }\n\n return undefined\n}\n\n/**\n * Transforms a projection result (with titleCandidates, subtitleCandidates, media)\n * into a PreviewValue (with title, subtitle, media).\n *\n * @param projectionResult - The raw projection result from GROQ\n * @param instance - The Sanity instance to use for client configuration\n * @param resource - Data resource for the preview\n * @internal\n */\nexport function transformProjectionToPreview(\n instance: SanityInstance,\n projectionResult: PreviewQueryResult,\n resource?: DocumentResource,\n): PreviewValue {\n const title = findFirstDefined(TITLE_CANDIDATES, projectionResult.titleCandidates)\n const subtitle = findFirstDefined(SUBTITLE_CANDIDATES, projectionResult.subtitleCandidates, title)\n\n // Get a client for the resource (if provided) or use the instance config\n const client = getClient(instance, {\n apiVersion: API_VERSION,\n resource,\n })\n\n return {\n title: String(title || `${projectionResult._type}: ${projectionResult._id}`),\n subtitle: subtitle || undefined,\n media: normalizeMedia(projectionResult.media, client),\n ...(projectionResult._status && {_status: projectionResult._status}),\n }\n}\n","/**\n * Telemetry environment classification.\n *\n * - `'development'` — the SDK is running on the local developer's machine\n * (`localhost` / `127.0.0.1` in the browser, or `NODE_ENV=development`\n * in Node). These are the original dev-only telemetry sessions.\n *\n * - `'production'` — the SDK is running on a production Sanity-controlled\n * domain (Studio deployments on `*.sanity.studio`, the dashboard on\n * `*.sanity.io`) where end users are authenticated Sanity users with\n * Populus consent records. Production telemetry is gated to this\n * allowlist; SDK apps deployed to customer-controlled domains do not\n * emit telemetry. Staging (`*.sanity.work`) and preview\n * (`*.sanity.dev`) hosts are deliberately excluded.\n *\n * @internal\n */\nexport type TelemetryEnvironment = 'development' | 'production'\n\n/**\n * Hostname suffixes that count as Sanity-controlled for the purposes of\n * production telemetry. A user reaching one of these hosts in the\n * browser is authenticated against Sanity and has a Populus consent\n * record, so we apply the same telemetry rules as the Studio's\n * `telemetry-sink`.\n *\n * The leading `.` is required: it ensures suffix matches hit a real\n * subdomain boundary, so apex matches (`sanity.io`, `sanity.studio`)\n * and lookalikes (`evilsanity.studio`) are excluded. Only production\n * hosts are listed; staging (`*.sanity.work`) and preview\n * (`*.sanity.dev`) hosts are excluded by omission.\n *\n * @internal\n */\nconst SANITY_CONTROLLED_HOST_SUFFIXES = ['.sanity.studio', '.sanity.io'] as const\n\nfunction getBrowserHostname(win: Window): string | null {\n const hostname = win.location?.hostname\n return typeof hostname === 'string' && hostname.length > 0 ? hostname.toLowerCase() : null\n}\n\nfunction isLocalHostname(hostname: string): boolean {\n return hostname === 'localhost' || hostname === '127.0.0.1'\n}\n\nfunction isSanityControlledHostname(hostname: string): boolean {\n return SANITY_CONTROLLED_HOST_SUFFIXES.some((suffix) => hostname.endsWith(suffix))\n}\n\n/**\n * Returns the telemetry environment for the current runtime, or `null`\n * when telemetry should not run at all.\n *\n * Browser:\n * - `localhost` / `127.0.0.1` → `'development'`\n * - host matches the Sanity-controlled allowlist → `'production'`\n * - anything else (customer domains, unknown contexts) → `null`\n *\n * Node (scripts, SSR, tests):\n * - `NODE_ENV=development` → `'development'`\n * - otherwise → `null`. Production-side server runtimes don't carry the\n * browser-authenticated user/consent assumption, so we don't enable\n * them under the production gate.\n *\n * Bracket-notation `process.env['NODE_ENV']` is used to avoid bundler\n * dead-code replacement.\n *\n * @internal\n */\nexport function getTelemetryEnvironment(): TelemetryEnvironment | null {\n if (typeof window !== 'undefined') {\n const hostname = getBrowserHostname(window)\n if (!hostname) return null\n if (isLocalHostname(hostname)) return 'development'\n if (isSanityControlledHostname(hostname)) return 'production'\n return null\n }\n\n if (typeof process !== 'undefined' && process.env?.['NODE_ENV'] === 'development') {\n return 'development'\n }\n return null\n}\n\n/**\n * Convenience predicate for \"telemetry can run in this environment\".\n *\n * @internal\n */\nexport function isTelemetryEnabled(): boolean {\n return getTelemetryEnvironment() !== null\n}\n","import {type SanityInstance} from '../store/createSanityInstance'\nimport {createLogger} from '../utils/logger'\nimport {getTelemetryEnvironment} from './environment'\nimport {type TelemetryManager} from './telemetryManager'\n\nconst DEFAULT_TELEMETRY_API_VERSION = '2024-11-12'\n\nconst logger = createLogger('telemetry')\n\n/**\n * Per-instance map of active telemetry managers. Allows the React\n * package (and other consumers) to look up the manager for a given\n * instance and log hook usage / errors without importing the full\n * telemetry module themselves.\n *\n * @internal\n */\nconst telemetryManagers = new WeakMap<SanityInstance, TelemetryManager>()\nconst pendingHooks = new WeakMap<SanityInstance, Set<string>>()\nconst initInFlight = new WeakSet<SanityInstance>()\n\n/**\n * Initializes telemetry for a SDK instance if the runtime environment\n * qualifies. The environment is resolved by `getTelemetryEnvironment()`:\n *\n * - `'development'` — local dev servers (`localhost` / `127.0.0.1`, or\n * Node with `NODE_ENV=development`). This is the original opt-in\n * surface.\n * - `'production'` — apps deployed to Sanity-controlled domains\n * (e.g. `*.sanity.studio`, the dashboard). End users are\n * authenticated Sanity users with Populus consent records, so we\n * apply the same consent gate as the Studio's `telemetry-sink`.\n *\n * Apps on customer-controlled domains return `null` and skip telemetry\n * entirely.\n *\n * `telemetryManager` and `clientStore` are dynamically imported so the\n * telemetry code path stays out of production bundles for apps that\n * don't qualify. Only the lightweight environment check runs at boot.\n *\n * The `projectId` must be passed explicitly because the resource\n * configuration is typically set by the React layer after the\n * instance has already been created.\n *\n * @internal\n */\nexport function initTelemetry(instance: SanityInstance, projectId: string): void {\n const environment = getTelemetryEnvironment()\n if (!environment) {\n logger.trace('initTelemetry skipped: environment not eligible', {internal: true})\n return\n }\n if (!projectId) {\n logger.trace('initTelemetry skipped: no projectId', {internal: true})\n return\n }\n if (telemetryManagers.has(instance) || initInFlight.has(instance)) {\n return\n }\n initInFlight.add(instance)\n\n logger.debug('initializing telemetry', {projectId, environment})\n\n Promise.all([\n import('./telemetryManager'),\n import('../client/clientStore'),\n import('../auth/authStore'),\n ])\n .then(async ([{createTelemetryManager}, {getClient}, {getTokenState}]) => {\n if (instance.isDisposed()) {\n initInFlight.delete(instance)\n logger.debug('telemetry skipped: instance disposed before imports resolved')\n return\n }\n\n // Wait for the auth store to resolve a token. The client needs a\n // Bearer token for the consent check and batch POSTs. If the token\n // is already available (e.g. static token config), this resolves\n // immediately. For OAuth/localStorage discovery it waits for the\n // first emission. For unauthenticated apps the promise never\n // resolves, which is fine since telemetry requires auth anyway.\n const token = getTokenState(instance).getCurrent()\n logger.trace('auth token check', {tokenPresent: !!token, internal: true})\n\n if (!token) {\n logger.debug('waiting for auth token')\n const hasToken = await new Promise<boolean>((resolve) => {\n if (instance.isDisposed()) return resolve(false)\n const cleanup = {unsubscribe: () => {}}\n const unsub = instance.onDispose(() => {\n cleanup.unsubscribe()\n resolve(false)\n })\n // The token observable is a `shareReplay({bufferSize: 1, refCount: true})`\n // (see `createStateSourceAction`), so it can deliver a buffered value\n // synchronously while we're still inside `.subscribe(cb)`. At that\n // moment `sub` is in the TDZ, so the callback can't reach it. We\n // gate on a `received` flag and let the post-subscribe block do the\n // unsubscribe in the sync-emission case.\n let received = false\n const sub = getTokenState(instance).observable.subscribe((t) => {\n if (received || !t) return\n received = true\n logger.debug('auth token received')\n unsub()\n resolve(true)\n cleanup.unsubscribe()\n })\n cleanup.unsubscribe = () => sub.unsubscribe()\n if (received) cleanup.unsubscribe()\n })\n if (!hasToken || instance.isDisposed()) {\n initInFlight.delete(instance)\n logger.debug('telemetry skipped: no token resolved or instance disposed')\n return\n }\n }\n\n const manager = createTelemetryManager({\n sessionId: instance.instanceId,\n getClient: () => getClient(instance, {apiVersion: DEFAULT_TELEMETRY_API_VERSION}),\n projectId,\n environment,\n })\n\n const consented = await manager.checkConsent()\n logger.debug('consent check complete', {consented})\n if (!consented || instance.isDisposed()) {\n initInFlight.delete(instance)\n manager.dispose()\n return\n }\n\n initInFlight.delete(instance)\n telemetryManagers.set(instance, manager)\n\n const buffered = pendingHooks.get(instance)\n if (buffered) {\n logger.debug('flushing buffered hooks', {hooks: Array.from(buffered)})\n for (const hookName of buffered) {\n manager.logHookFirstUsed(hookName)\n }\n pendingHooks.delete(instance)\n }\n\n const config = instance.config\n const perspective = typeof config.perspective === 'string' ? config.perspective : 'published'\n const authMethod = config.auth?.token\n ? 'token'\n : config.studio?.auth?.token\n ? 'studio'\n : 'default'\n\n logger.info('telemetry session started', {projectId, perspective, authMethod, environment})\n manager.logSessionStarted({\n projectId,\n perspective,\n authMethod,\n })\n\n instance.onDispose(() => {\n manager.endSession()\n telemetryManagers.delete(instance)\n logger.debug('telemetry session ended')\n })\n })\n .catch((err) => {\n initInFlight.delete(instance)\n logger.warn('telemetry init failed', {error: err})\n })\n}\n\n/**\n * Retrieves the telemetry manager for an instance, if one exists.\n * Returns undefined when telemetry is disabled or not yet initialized.\n *\n * @internal\n */\nexport function getTelemetryManager(instance: SanityInstance): TelemetryManager | undefined {\n return telemetryManagers.get(instance)\n}\n\n/**\n * Record a hook name for an instance. If the telemetry manager is\n * already initialized the event is logged immediately. Otherwise\n * the name is buffered and flushed when init completes.\n *\n * @internal\n */\nexport function trackHookMounted(instance: SanityInstance, hookName: string): void {\n if (!getTelemetryEnvironment()) return\n\n const manager = findManager(instance)\n if (manager) {\n logger.trace('hook mounted (logged)', {hookName, internal: true})\n manager.logHookFirstUsed(hookName)\n return\n }\n\n const root = getRootInstance(instance)\n let hooks = pendingHooks.get(root)\n if (!hooks) {\n hooks = new Set()\n pendingHooks.set(root, hooks)\n }\n if (!hooks.has(hookName)) {\n logger.trace('hook mounted (buffered)', {hookName, internal: true})\n }\n hooks.add(hookName)\n}\n\nfunction findManager(instance: SanityInstance): TelemetryManager | undefined {\n return telemetryManagers.get(instance)\n}\n\nfunction getRootInstance(instance: SanityInstance): SanityInstance {\n return instance\n}\n","const WILDCARD_TOKEN = '*'\nconst NEGATION_TOKEN = '-'\n// This regex handles simple cases including quoted phrases.\n// More complex query syntaxes might need a more robust parser.\nconst TOKEN_REGEX = /(?:[^\\s\"]+|\"[^\"]*\")+/g\n\n/**\n * @internal\n * Checks if a token starts with the negation character.\n */\nfunction isNegationToken(token: string | undefined): boolean {\n return typeof token !== 'undefined' && token.trim().startsWith(NEGATION_TOKEN)\n}\n\n/**\n * @internal\n * Checks if a token ends with the wildcard character.\n */\nfunction isPrefixToken(token: string | undefined): boolean {\n return typeof token !== 'undefined' && token.trim().endsWith(WILDCARD_TOKEN)\n}\n\n/**\n * @internal\n * Checks if a token is enclosed in double quotes.\n */\nfunction isExactMatchToken(token: string | undefined): boolean {\n // Ensure the token exists, has at least 2 characters, and starts/ends with \"\n return !!token && token.length >= 2 && token.startsWith('\"') && token.endsWith('\"')\n}\n\n/**\n * Creates a GROQ search filter string (`[@] match text::query(\"...\")`)\n * from a raw search query string.\n *\n * It applies wildcard ('*') logic to the last eligible token and escapes\n * double quotes within the search term.\n *\n * If the input query is empty or only whitespace, it returns an empty string.\n *\n * @param query - The raw input search string.\n * @returns The GROQ search filter string, or an empty string.\n * @internal\n */\nexport function createGroqSearchFilter(query: string): string {\n // Trim leading/trailing whitespace from the overall query first\n const trimmedQuery = query.trim()\n if (!trimmedQuery) {\n return '' // Return empty if query is empty or just whitespace\n }\n\n // Extract tokens using the regex\n const tokens = trimmedQuery.match(TOKEN_REGEX) ?? []\n\n // Find the index of the last token eligible for wildcard appending\n const reversedTokens = [...tokens].reverse()\n const reversedIndex = reversedTokens.findIndex(\n (token: string) => !isNegationToken(token) && !isExactMatchToken(token),\n )\n const finalIncrementalTokenIndex = reversedIndex === -1 ? -1 : tokens.length - 1 - reversedIndex\n\n // Get the actual token based on the found index\n const finalIncrementalToken = tokens[finalIncrementalTokenIndex]\n\n const processedTokens = [...tokens]\n // If a suitable token was found and it doesn't already end with a wildcard,\n // apply the wildcard.\n if (finalIncrementalToken !== undefined && !isPrefixToken(finalIncrementalToken)) {\n // Replace the identified token with its wildcarded version\n processedTokens.splice(\n finalIncrementalTokenIndex,\n 1,\n `${finalIncrementalToken}${WILDCARD_TOKEN}`,\n )\n }\n\n // Join the tokens back into a space-separated string\n const wildcardSearch = processedTokens.join(' ')\n\n // Escape double quotes within the final search term for the GROQ query\n const escapedSearch = wildcardSearch.replace(/\"/g, '\\\\\"')\n\n // Construct the final GROQ filter clause\n return `[@] match text::query(\"${escapedSearch}\")`\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"_internal.js","names":[],"sources":["../../src/preview/previewConstants.ts","../../src/preview/previewProjectionUtils.ts","../../src/telemetry/environment.ts","../../src/telemetry/events.ts","../../src/telemetry/telemetryManager.ts","../../src/telemetry/initTelemetry.ts","../../src/utils/createGroqSearchFilter.ts"],"sourcesContent":["/**\n * The fields to check for a title.\n * The order of the items in the array defines the priority.\n *\n * @internal\n */\nexport const TITLE_CANDIDATES = ['title', 'name', 'label', 'heading', 'header', 'caption']\n\n/**\n * The fields to check for a subtitle.\n * The order of the items in the array defines the priority.\n *\n * @internal\n */\nexport const SUBTITLE_CANDIDATES = ['description', 'subtitle', ...TITLE_CANDIDATES]\n\n/**\n * Generates a GROQ projection for preview data without requiring a schema.\n * Uses common field names to make educated guesses about which fields to use.\n *\n * @internal\n */\nexport const PREVIEW_PROJECTION = `{\n // Get all potential title fields\n \"titleCandidates\": {\n ${TITLE_CANDIDATES.map((field) => `\"${field}\": ${field}`).join(',\\n ')}\n },\n // Get all potential subtitle fields\n \"subtitleCandidates\": {\n ${SUBTITLE_CANDIDATES.map((field) => `\"${field}\": ${field}`).join(',\\n ')}\n },\n \"media\": coalesce(\n select(\n defined(asset) => {\"type\": \"image-asset\", \"_ref\": asset._ref},\n defined(image.asset) => {\"type\": \"image-asset\", \"_ref\": image.asset._ref},\n defined(mainImage.asset) => {\"type\": \"image-asset\", \"_ref\": mainImage.asset._ref},\n null\n )\n ),\n _type,\n _id,\n _updatedAt\n}`\n","import {type SanityClient} from '@sanity/client'\nimport {createImageUrlBuilder} from '@sanity/image-url'\n\nimport {getClient} from '../client/clientStore'\nimport {type DocumentResource} from '../config/sanityConfig'\nimport {type SanityInstance} from '../store/createSanityInstance'\nimport {isObject} from '../utils/object'\nimport {SUBTITLE_CANDIDATES, TITLE_CANDIDATES} from './previewConstants'\nimport {type PreviewQueryResult, type PreviewValue} from './types'\n\nconst API_VERSION = 'v2025-05-06'\n\n/**\n * Checks if the provided value has `_ref` property that is a string and starts with `image-`\n */\nfunction hasImageRef<T>(value: unknown): value is T & {_ref: string} {\n return isObject(value) && '_ref' in value && typeof (value as {_ref: unknown})._ref === 'string'\n}\n\n/**\n * Normalizes a media asset to a preview value.\n * Adds a url to a media asset reference using `@sanity/image-url`.\n *\n * @internal\n */\nexport function normalizeMedia(media: unknown, client: SanityClient): PreviewValue['media'] {\n if (!media) return null\n if (!hasImageRef(media)) return null\n\n const builder = createImageUrlBuilder(client)\n const url = builder.image({_ref: media._ref}).url()\n\n return {\n type: 'image-asset',\n _ref: media._ref,\n url,\n }\n}\n\n/**\n * Finds a single field value from a set of candidates based on a priority list of field names.\n * Returns the first non-empty string value found from the candidates matching the priority list order.\n *\n * @internal\n */\nfunction findFirstDefined(\n fieldsToSearch: string[],\n candidates: Record<string, unknown>,\n exclude?: unknown,\n): string | undefined {\n if (!candidates) return undefined\n\n for (const field of fieldsToSearch) {\n const value = candidates[field]\n if (typeof value === 'string' && value.trim() !== '' && value !== exclude) {\n return value\n }\n }\n\n return undefined\n}\n\n/**\n * Transforms a projection result (with titleCandidates, subtitleCandidates, media)\n * into a PreviewValue (with title, subtitle, media).\n *\n * @param projectionResult - The raw projection result from GROQ\n * @param instance - The Sanity instance to use for client configuration\n * @param resource - Data resource for the preview\n * @internal\n */\nexport function transformProjectionToPreview(\n instance: SanityInstance,\n projectionResult: PreviewQueryResult,\n resource?: DocumentResource,\n): PreviewValue {\n const title = findFirstDefined(TITLE_CANDIDATES, projectionResult.titleCandidates)\n const subtitle = findFirstDefined(SUBTITLE_CANDIDATES, projectionResult.subtitleCandidates, title)\n\n // Get a client for the resource (if provided) or use the instance config\n const client = getClient(instance, {\n apiVersion: API_VERSION,\n resource,\n })\n\n return {\n title: String(title || `${projectionResult._type}: ${projectionResult._id}`),\n subtitle: subtitle || undefined,\n media: normalizeMedia(projectionResult.media, client),\n ...(projectionResult._status && {_status: projectionResult._status}),\n }\n}\n","/**\n * Telemetry environment classification.\n *\n * - `'development'` — the SDK is running on the local developer's machine\n * (`localhost` / `127.0.0.1` in the browser, or `NODE_ENV=development`\n * in Node). These are the original dev-only telemetry sessions.\n *\n * - `'production'` — the SDK is running on a production Sanity-controlled\n * domain (Studio deployments on `*.sanity.studio`, the dashboard on\n * `*.sanity.io`) where end users are authenticated Sanity users with\n * Populus consent records. Production telemetry is gated to this\n * allowlist; SDK apps deployed to customer-controlled domains do not\n * emit telemetry. Staging (`*.sanity.work`) and preview\n * (`*.sanity.dev`) hosts are deliberately excluded.\n *\n * @internal\n */\nexport type TelemetryEnvironment = 'development' | 'production'\n\n/**\n * Hostname suffixes that count as Sanity-controlled for the purposes of\n * production telemetry. A user reaching one of these hosts in the\n * browser is authenticated against Sanity and has a Populus consent\n * record, so we apply the same telemetry rules as the Studio's\n * `telemetry-sink`.\n *\n * The leading `.` is required: it ensures suffix matches hit a real\n * subdomain boundary, so apex matches (`sanity.io`, `sanity.studio`)\n * and lookalikes (`evilsanity.studio`) are excluded. Only production\n * hosts are listed; staging (`*.sanity.work`) and preview\n * (`*.sanity.dev`) hosts are excluded by omission.\n *\n * @internal\n */\nconst SANITY_CONTROLLED_HOST_SUFFIXES = ['.sanity.studio', '.sanity.io'] as const\n\nfunction getBrowserHostname(win: Window): string | null {\n const hostname = win.location?.hostname\n return typeof hostname === 'string' && hostname.length > 0 ? hostname.toLowerCase() : null\n}\n\nfunction isLocalHostname(hostname: string): boolean {\n return hostname === 'localhost' || hostname === '127.0.0.1'\n}\n\nfunction isSanityControlledHostname(hostname: string): boolean {\n return SANITY_CONTROLLED_HOST_SUFFIXES.some((suffix) => hostname.endsWith(suffix))\n}\n\n/**\n * Returns the telemetry environment for the current runtime, or `null`\n * when telemetry should not run at all.\n *\n * Browser:\n * - `localhost` / `127.0.0.1` → `'development'`\n * - host matches the Sanity-controlled allowlist → `'production'`\n * - anything else (customer domains, unknown contexts) → `null`\n *\n * Node (scripts, SSR, tests):\n * - `NODE_ENV=development` → `'development'`\n * - otherwise → `null`. Production-side server runtimes don't carry the\n * browser-authenticated user/consent assumption, so we don't enable\n * them under the production gate.\n *\n * Bracket-notation `process.env['NODE_ENV']` is used to avoid bundler\n * dead-code replacement.\n *\n * @internal\n */\nexport function getTelemetryEnvironment(): TelemetryEnvironment | null {\n if (typeof window !== 'undefined') {\n const hostname = getBrowserHostname(window)\n if (!hostname) return null\n if (isLocalHostname(hostname)) return 'development'\n if (isSanityControlledHostname(hostname)) return 'production'\n return null\n }\n\n if (typeof process !== 'undefined' && process.env?.['NODE_ENV'] === 'development') {\n return 'development'\n }\n return null\n}\n\n/**\n * Convenience predicate for \"telemetry can run in this environment\".\n *\n * @internal\n */\nexport function isTelemetryEnabled(): boolean {\n return getTelemetryEnvironment() !== null\n}\n","import {defineEvent} from '@sanity/telemetry'\n\n/** @internal */\nexport const SDKSessionStarted = defineEvent<{\n version: string\n projectId: string\n perspective: string\n authMethod: string\n}>({\n name: 'SDK Session Started',\n version: 1,\n description: 'SDK instance created (environment is recorded in the event context)',\n})\n\n/** @internal */\nexport const SDKHookMounted = defineEvent<{\n hookName: string\n}>({\n name: 'SDK Hook Mounted',\n version: 1,\n description: 'An SDK hook was mounted for the first time in this session',\n})\n\n/** @internal */\nexport const SDKSessionEnded = defineEvent<{\n durationSeconds: number\n hooksUsed: string[]\n}>({\n name: 'SDK Session Ended',\n version: 1,\n description: 'SDK instance disposed (environment is recorded in the event context)',\n})\n\n/** @internal */\nexport const SDKError = defineEvent<{\n errorType: string\n hookName: string\n}>({\n name: 'SDK Error',\n version: 1,\n description: 'Runtime error caught in the SDK',\n})\n","import {type SanityClient} from '@sanity/client'\nimport {\n type ConsentStatus,\n createBatchedStore,\n type SessionId,\n type TelemetryEvent,\n type TelemetryLogger,\n type TelemetryStore,\n} from '@sanity/telemetry'\n\nimport {createLogger} from '../utils/logger'\nimport {CORE_SDK_VERSION} from '../version'\nimport {type TelemetryEnvironment} from './environment'\nimport {SDKError, SDKHookMounted, SDKSessionEnded, SDKSessionStarted} from './events'\n\nconst FLUSH_INTERVAL_MS = 30_000\nconst CONSENT_TAG = 'telemetry-consent.sdk'\nconst BATCH_TAG = 'telemetry.batch'\n\nconst log = createLogger('telemetry')\n\n/**\n * Manages telemetry for a single SDK instance.\n *\n * Wraps `@sanity/telemetry`'s batched store with SDK-specific concerns:\n * consent caching, session lifecycle events, and hook usage tracking.\n * The `environment` is captured at construction time and recorded in\n * the event context so downstream pipelines can distinguish dev and\n * production sessions.\n *\n * @internal\n */\nexport interface TelemetryManager {\n /**\n * Eagerly resolve and cache the user's consent status.\n * Returns true only when the user has explicitly opted in (`granted`).\n * Call this before logging any events to avoid buffering events that\n * will be dropped on the first flush.\n */\n checkConsent(): Promise<boolean>\n\n /** Log a \"SDK Session Started\" event */\n logSessionStarted(data: {projectId: string; perspective: string; authMethod: string}): void\n\n /** Log a \"SDK Hook Mounted\" event (deduplicated per hook name) */\n logHookFirstUsed(hookName: string): void\n\n /** Log a \"SDK Error\" event */\n logError(errorType: string, hookName: string): void\n\n /** Log a \"SDK Session Ended\" event and tear down the store */\n endSession(): void\n\n /** Tear down the store without logging a session-end event */\n dispose(): void\n\n /** The set of hook names used during this session */\n readonly hooksUsed: ReadonlySet<string>\n}\n\ninterface TelemetryManagerOptions {\n sessionId: string\n getClient: () => SanityClient\n projectId: string\n environment: TelemetryEnvironment\n}\n\n/**\n * Creates a telemetry manager for a single SDK instance session.\n *\n * The manager initializes a `createBatchedStore` from `@sanity/telemetry`,\n * caches the consent check for the lifetime of the session, and provides\n * typed methods for each SDK telemetry event.\n *\n * @internal\n */\nexport function createTelemetryManager(options: TelemetryManagerOptions): TelemetryManager {\n const {sessionId, getClient, projectId, environment} = options\n const startedAt = Date.now()\n const emittedHooks = new Set<string>()\n\n let cachedConsent: {status: ConsentStatus} | null = null\n\n const resolveConsent = async (): Promise<{status: ConsentStatus}> => {\n if (cachedConsent) return cachedConsent\n try {\n const client = getClient()\n const result = await client.request<{status: ConsentStatus}>({\n url: '/intake/telemetry-status',\n tag: CONSENT_TAG,\n })\n cachedConsent = result\n } catch {\n cachedConsent = {status: 'undetermined'}\n }\n return cachedConsent\n }\n\n const enrichBatch = (batch: TelemetryEvent[]) =>\n batch.map((event) => {\n // Trace events (`trace.start` / `trace.log` / `trace.error` /\n // `trace.complete`) arrive with their own caller-provided `context`.\n // Log / userProperties events don't. Narrow via `in` so `event`\n // stays typed as `TelemetryEvent`, then merge so we don't drop the\n // trace context. SDK-owned fields below win on conflict.\n const existing =\n 'context' in event ? (event.context as Record<string, unknown> | undefined) : undefined\n return {\n ...event,\n context: {\n ...existing,\n version: CORE_SDK_VERSION,\n environment,\n origin: typeof window !== 'undefined' ? window.location.origin : 'node',\n },\n }\n })\n\n const sendEvents = async (batch: TelemetryEvent[]): Promise<unknown> => {\n const client = getClient()\n log.debug('sending event batch', {batchSize: batch.length, environment})\n return client.request({\n url: '/intake/batch',\n method: 'POST',\n body: {projectId, batch: enrichBatch(batch)},\n tag: BATCH_TAG,\n })\n }\n\n const store: TelemetryStore<Record<string, unknown>> = createBatchedStore(\n sessionId as SessionId,\n {\n flushInterval: FLUSH_INTERVAL_MS,\n resolveConsent,\n sendEvents,\n },\n )\n\n const logger: TelemetryLogger<Record<string, unknown>> = store.logger\n\n return {\n async checkConsent() {\n const {status} = await resolveConsent()\n return status === 'granted'\n },\n\n logSessionStarted(data) {\n log.debug('event: SDK Session Started', {\n projectId: data.projectId,\n perspective: data.perspective,\n authMethod: data.authMethod,\n version: CORE_SDK_VERSION,\n environment,\n })\n logger.log(SDKSessionStarted, {\n version: CORE_SDK_VERSION,\n ...data,\n })\n },\n\n logHookFirstUsed(hookName: string) {\n if (emittedHooks.has(hookName)) return\n emittedHooks.add(hookName)\n log.debug('event: SDK Hook Mounted', {hookName})\n logger.log(SDKHookMounted, {hookName})\n },\n\n logError(errorType: string, hookName: string) {\n log.debug('event: SDK Error', {errorType, hookName})\n logger.log(SDKError, {errorType, hookName})\n },\n\n endSession() {\n const durationSeconds = Math.round((Date.now() - startedAt) / 1000)\n log.debug('event: SDK Session Ended', {\n durationSeconds,\n hooksUsed: [...emittedHooks],\n environment,\n })\n logger.log(SDKSessionEnded, {\n durationSeconds,\n hooksUsed: [...emittedHooks],\n })\n\n store.flush().catch(() => {\n // Best-effort flush on dispose; swallow errors\n })\n store.end()\n },\n\n dispose() {\n store.end()\n },\n\n get hooksUsed(): ReadonlySet<string> {\n return emittedHooks\n },\n }\n}\n","import {type SanityInstance} from '../store/createSanityInstance'\nimport {createLogger} from '../utils/logger'\nimport {getTelemetryEnvironment} from './environment'\nimport {type TelemetryManager} from './telemetryManager'\n\nconst DEFAULT_TELEMETRY_API_VERSION = '2024-11-12'\n\nconst logger = createLogger('telemetry')\n\n/**\n * Per-instance map of active telemetry managers. Allows the React\n * package (and other consumers) to look up the manager for a given\n * instance and log hook usage / errors without importing the full\n * telemetry module themselves.\n *\n * @internal\n */\nconst telemetryManagers = new WeakMap<SanityInstance, TelemetryManager>()\nconst pendingHooks = new WeakMap<SanityInstance, Set<string>>()\nconst initInFlight = new WeakSet<SanityInstance>()\n\n/**\n * Initializes telemetry for a SDK instance if the runtime environment\n * qualifies. The environment is resolved by `getTelemetryEnvironment()`:\n *\n * - `'development'` — local dev servers (`localhost` / `127.0.0.1`, or\n * Node with `NODE_ENV=development`). This is the original opt-in\n * surface.\n * - `'production'` — apps deployed to Sanity-controlled domains\n * (e.g. `*.sanity.studio`, the dashboard). End users are\n * authenticated Sanity users with Populus consent records, so we\n * apply the same consent gate as the Studio's `telemetry-sink`.\n *\n * Apps on customer-controlled domains return `null` and skip telemetry\n * entirely.\n *\n * `telemetryManager` and `clientStore` are dynamically imported so the\n * telemetry code path stays out of production bundles for apps that\n * don't qualify. Only the lightweight environment check runs at boot.\n *\n * The `projectId` must be passed explicitly because the resource\n * configuration is typically set by the React layer after the\n * instance has already been created.\n *\n * @internal\n */\nexport function initTelemetry(instance: SanityInstance, projectId: string): void {\n const environment = getTelemetryEnvironment()\n if (!environment) {\n logger.trace('initTelemetry skipped: environment not eligible', {internal: true})\n return\n }\n if (!projectId) {\n logger.trace('initTelemetry skipped: no projectId', {internal: true})\n return\n }\n if (telemetryManagers.has(instance) || initInFlight.has(instance)) {\n return\n }\n initInFlight.add(instance)\n\n logger.debug('initializing telemetry', {projectId, environment})\n\n Promise.all([\n import('./telemetryManager'),\n import('../client/clientStore'),\n import('../auth/authStore'),\n ])\n .then(async ([{createTelemetryManager}, {getClient}, {getTokenState}]) => {\n if (instance.isDisposed()) {\n initInFlight.delete(instance)\n logger.debug('telemetry skipped: instance disposed before imports resolved')\n return\n }\n\n // Wait for the auth store to resolve a token. The client needs a\n // Bearer token for the consent check and batch POSTs. If the token\n // is already available (e.g. static token config), this resolves\n // immediately. For OAuth/localStorage discovery it waits for the\n // first emission. For unauthenticated apps the promise never\n // resolves, which is fine since telemetry requires auth anyway.\n const token = getTokenState(instance).getCurrent()\n logger.trace('auth token check', {tokenPresent: !!token, internal: true})\n\n if (!token) {\n logger.debug('waiting for auth token')\n const hasToken = await new Promise<boolean>((resolve) => {\n if (instance.isDisposed()) return resolve(false)\n const cleanup = {unsubscribe: () => {}}\n const unsub = instance.onDispose(() => {\n cleanup.unsubscribe()\n resolve(false)\n })\n // The token observable is a `shareReplay({bufferSize: 1, refCount: true})`\n // (see `createStateSourceAction`), so it can deliver a buffered value\n // synchronously while we're still inside `.subscribe(cb)`. At that\n // moment `sub` is in the TDZ, so the callback can't reach it. We\n // gate on a `received` flag and let the post-subscribe block do the\n // unsubscribe in the sync-emission case.\n let received = false\n const sub = getTokenState(instance).observable.subscribe((t) => {\n if (received || !t) return\n received = true\n logger.debug('auth token received')\n unsub()\n resolve(true)\n cleanup.unsubscribe()\n })\n cleanup.unsubscribe = () => sub.unsubscribe()\n if (received) cleanup.unsubscribe()\n })\n if (!hasToken || instance.isDisposed()) {\n initInFlight.delete(instance)\n logger.debug('telemetry skipped: no token resolved or instance disposed')\n return\n }\n }\n\n const manager = createTelemetryManager({\n sessionId: instance.instanceId,\n getClient: () => getClient(instance, {apiVersion: DEFAULT_TELEMETRY_API_VERSION}),\n projectId,\n environment,\n })\n\n const consented = await manager.checkConsent()\n logger.debug('consent check complete', {consented})\n if (!consented || instance.isDisposed()) {\n initInFlight.delete(instance)\n manager.dispose()\n return\n }\n\n initInFlight.delete(instance)\n telemetryManagers.set(instance, manager)\n\n const buffered = pendingHooks.get(instance)\n if (buffered) {\n logger.debug('flushing buffered hooks', {hooks: Array.from(buffered)})\n for (const hookName of buffered) {\n manager.logHookFirstUsed(hookName)\n }\n pendingHooks.delete(instance)\n }\n\n const config = instance.config\n const perspective = typeof config.perspective === 'string' ? config.perspective : 'published'\n const authMethod = config.auth?.token\n ? 'token'\n : config.studio?.auth?.token\n ? 'studio'\n : 'default'\n\n logger.info('telemetry session started', {projectId, perspective, authMethod, environment})\n manager.logSessionStarted({\n projectId,\n perspective,\n authMethod,\n })\n\n instance.onDispose(() => {\n manager.endSession()\n telemetryManagers.delete(instance)\n logger.debug('telemetry session ended')\n })\n })\n .catch((err) => {\n initInFlight.delete(instance)\n logger.warn('telemetry init failed', {error: err})\n })\n}\n\n/**\n * Retrieves the telemetry manager for an instance, if one exists.\n * Returns undefined when telemetry is disabled or not yet initialized.\n *\n * @internal\n */\nexport function getTelemetryManager(instance: SanityInstance): TelemetryManager | undefined {\n return telemetryManagers.get(instance)\n}\n\n/**\n * Record a hook name for an instance. If the telemetry manager is\n * already initialized the event is logged immediately. Otherwise\n * the name is buffered and flushed when init completes.\n *\n * @internal\n */\nexport function trackHookMounted(instance: SanityInstance, hookName: string): void {\n if (!getTelemetryEnvironment()) return\n\n const manager = findManager(instance)\n if (manager) {\n logger.trace('hook mounted (logged)', {hookName, internal: true})\n manager.logHookFirstUsed(hookName)\n return\n }\n\n const root = getRootInstance(instance)\n let hooks = pendingHooks.get(root)\n if (!hooks) {\n hooks = new Set()\n pendingHooks.set(root, hooks)\n }\n if (!hooks.has(hookName)) {\n logger.trace('hook mounted (buffered)', {hookName, internal: true})\n }\n hooks.add(hookName)\n}\n\nfunction findManager(instance: SanityInstance): TelemetryManager | undefined {\n return telemetryManagers.get(instance)\n}\n\nfunction getRootInstance(instance: SanityInstance): SanityInstance {\n return instance\n}\n","const WILDCARD_TOKEN = '*'\nconst NEGATION_TOKEN = '-'\n// This regex handles simple cases including quoted phrases.\n// More complex query syntaxes might need a more robust parser.\nconst TOKEN_REGEX = /(?:[^\\s\"]+|\"[^\"]*\")+/g\n\n/**\n * @internal\n * Checks if a token starts with the negation character.\n */\nfunction isNegationToken(token: string | undefined): boolean {\n return typeof token !== 'undefined' && token.trim().startsWith(NEGATION_TOKEN)\n}\n\n/**\n * @internal\n * Checks if a token ends with the wildcard character.\n */\nfunction isPrefixToken(token: string | undefined): boolean {\n return typeof token !== 'undefined' && token.trim().endsWith(WILDCARD_TOKEN)\n}\n\n/**\n * @internal\n * Checks if a token is enclosed in double quotes.\n */\nfunction isExactMatchToken(token: string | undefined): boolean {\n // Ensure the token exists, has at least 2 characters, and starts/ends with \"\n return !!token && token.length >= 2 && token.startsWith('\"') && token.endsWith('\"')\n}\n\n/**\n * Creates a GROQ search filter string (`[@] match text::query(\"...\")`)\n * from a raw search query string.\n *\n * It applies wildcard ('*') logic to the last eligible token and escapes\n * double quotes within the search term.\n *\n * If the input query is empty or only whitespace, it returns an empty string.\n *\n * @param query - The raw input search string.\n * @returns The GROQ search filter string, or an empty string.\n * @internal\n */\nexport function createGroqSearchFilter(query: string): string {\n // Trim leading/trailing whitespace from the overall query first\n const trimmedQuery = query.trim()\n if (!trimmedQuery) {\n return '' // Return empty if query is empty or just whitespace\n }\n\n // Extract tokens using the regex\n const tokens = trimmedQuery.match(TOKEN_REGEX) ?? []\n\n // Find the index of the last token eligible for wildcard appending\n const reversedTokens = [...tokens].reverse()\n const reversedIndex = reversedTokens.findIndex(\n (token: string) => !isNegationToken(token) && !isExactMatchToken(token),\n )\n const finalIncrementalTokenIndex = reversedIndex === -1 ? -1 : tokens.length - 1 - reversedIndex\n\n // Get the actual token based on the found index\n const finalIncrementalToken = tokens[finalIncrementalTokenIndex]\n\n const processedTokens = [...tokens]\n // If a suitable token was found and it doesn't already end with a wildcard,\n // apply the wildcard.\n if (finalIncrementalToken !== undefined && !isPrefixToken(finalIncrementalToken)) {\n // Replace the identified token with its wildcarded version\n processedTokens.splice(\n finalIncrementalTokenIndex,\n 1,\n `${finalIncrementalToken}${WILDCARD_TOKEN}`,\n )\n }\n\n // Join the tokens back into a space-separated string\n const wildcardSearch = processedTokens.join(' ')\n\n // Escape double quotes within the final search term for the GROQ query\n const escapedSearch = wildcardSearch.replace(/\"/g, '\\\\\"')\n\n // Construct the final GROQ filter clause\n return `[@] match text::query(\"${escapedSearch}\")`\n}\n"],"mappings":";;;;;;;;;;;;AAMA,MAAa,mBAAmB;CAAC;CAAS;CAAQ;CAAS;CAAW;CAAU;AAAS,GAQ5E,sBAAsB;CAAC;CAAe;CAAY,GAAG;AAAgB,GAQrE,qBAAqB;;;MAG5B,iBAAiB,KAAK,UAAU,IAAI,MAAM,KAAK,OAAO,CAAC,CAAC,KAAK,WAAW,EAAE;;;;MAI1E,oBAAoB,KAAK,UAAU,IAAI,MAAM,KAAK,OAAO,CAAC,CAAC,KAAK,WAAW,EAAE;;;;;;;;;;;;;;;;;ACdnF,SAAS,YAAe,OAA6C;CACnE,OAAO,SAAS,KAAK,KAAK,UAAU,SAAS,OAAQ,MAA0B,QAAS;AAC1F;;;;;;;AAQA,SAAgB,eAAe,OAAgB,QAA6C;CAE1F,IADI,CAAC,SACD,CAAC,YAAY,KAAK,GAAG,OAAO;CAGhC,IAAM,MADU,sBAAsB,MACpB,CAAC,CAAC,MAAM,EAAC,MAAM,MAAM,KAAI,CAAC,CAAC,CAAC,IAAI;CAElD,OAAO;EACL,MAAM;EACN,MAAM,MAAM;EACZ;CACF;AACF;;;;;;;AAQA,SAAS,iBACP,gBACA,YACA,SACoB;CACf,gBAEL,KAAK,IAAM,SAAS,gBAAgB;EAClC,IAAM,QAAQ,WAAW;EACzB,IAAI,OAAO,SAAU,YAAY,MAAM,KAAK,MAAM,MAAM,UAAU,SAChE,OAAO;CAEX;AAGF;;;;;;;;;;AAWA,SAAgB,6BACd,UACA,kBACA,UACc;CACd,IAAM,QAAQ,iBAAiB,kBAAkB,iBAAiB,eAAe,GAC3E,WAAW,iBAAiB,qBAAqB,iBAAiB,oBAAoB,KAAK,GAG3F,SAAS,UAAU,UAAU;EACjC,YAAY;EACZ;CACF,CAAC;CAED,OAAO;EACL,OAAO,OAAO,SAAS,GAAG,iBAAiB,MAAM,IAAI,iBAAiB,KAAK;EAC3E,UAAU,YAAY,KAAA;EACtB,OAAO,eAAe,iBAAiB,OAAO,MAAM;EACpD,GAAI,iBAAiB,WAAW,EAAC,SAAS,iBAAiB,QAAO;CACpE;AACF;;;;;;;;;;;;;;;;ACzDA,MAAM,kCAAkC,CAAC,kBAAkB,YAAY;AAEvE,SAAS,mBAAmB,KAA4B;CACtD,IAAM,WAAW,IAAI,UAAU;CAC/B,OAAO,OAAO,YAAa,YAAY,SAAS,SAAS,IAAI,SAAS,YAAY,IAAI;AACxF;AAEA,SAAS,gBAAgB,UAA2B;CAClD,OAAO,aAAa,eAAe,aAAa;AAClD;AAEA,SAAS,2BAA2B,UAA2B;CAC7D,OAAO,gCAAgC,MAAM,WAAW,SAAS,SAAS,MAAM,CAAC;AACnF;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,0BAAuD;CACrE,IAAI,OAAO,SAAW,KAAa;EACjC,IAAM,WAAW,mBAAmB,MAAM;EAI1C,OAHK,WACD,gBAAgB,QAAQ,IAAU,gBAClC,2BAA2B,QAAQ,IAAU,eAC1C,OAHe;CAIxB;CAKA,OAHI,OAAO,UAAY,OAAe,QAAQ,KAAM,aAAgB,gBAC3D,gBAEF;AACT;;AC/EA,MAAa,oBAAoB,YAK9B;CACD,MAAM;CACN,SAAS;CACT,aAAa;AACf,CAAC,GAGY,iBAAiB,YAE3B;CACD,MAAM;CACN,SAAS;CACT,aAAa;AACf,CAAC,GAGY,kBAAkB,YAG5B;CACD,MAAM;CACN,SAAS;CACT,aAAa;AACf,CAAC,GAGY,WAAW,YAGrB;CACD,MAAM;CACN,SAAS;CACT,aAAa;AACf,CAAC;;AC1BD,MAIM,MAAM,aAAa,WAAW;;;;;;;;;;AAyDpC,SAAgB,uBAAuB,SAAoD;CACzF,IAAM,EAAC,WAAW,WAAW,WAAW,gBAAe,SACjD,YAAY,KAAK,IAAI,GACrB,+BAAe,IAAI,IAAY,GAEjC,gBAAgD,MAE9C,iBAAiB,YAA8C;EACnE,IAAI,eAAe,OAAO;EAC1B,IAAI;GAMF,gBAAgB,MALD,UACW,CAAC,CAAC,QAAiC;IAC3D,KAAK;IACL,KAAK;GACP,CAAC;EAEH,QAAQ;GACN,gBAAgB,EAAC,QAAQ,eAAc;EACzC;EACA,OAAO;CACT,GAEM,eAAe,UACnB,MAAM,KAAK,UAAU;EAMnB,IAAM,WACJ,aAAa,QAAS,MAAM,UAAkD,KAAA;EAChF,OAAO;GACL,GAAG;GACH,SAAS;IACP,GAAG;IACH,SAAS;IACT;IACA,QAAQ,OAAO,SAAW,MAAc,OAAO,SAAS,SAAS;GACnE;EACF;CACF,CAAC,GAEG,aAAa,OAAO,UAA8C;EACtE,IAAM,SAAS,UAAU;EAEzB,OADA,IAAI,MAAM,uBAAuB;GAAC,WAAW,MAAM;GAAQ;EAAW,CAAC,GAChE,OAAO,QAAQ;GACpB,KAAK;GACL,QAAQ;GACR,MAAM;IAAC;IAAW,OAAO,YAAY,KAAK;GAAC;GAC3C,KAAK;EACP,CAAC;CACH,GAEM,QAAiD,mBACrD,WACA;EACE,eAAe;EACf;EACA;CACF,CACF,GAEM,SAAmD,MAAM;CAE/D,OAAO;EACL,MAAM,eAAe;GACnB,IAAM,EAAC,WAAU,MAAM,eAAe;GACtC,OAAO,WAAW;EACpB;EAEA,kBAAkB,MAAM;GAQtB,AAPA,IAAI,MAAM,8BAA8B;IACtC,WAAW,KAAK;IAChB,aAAa,KAAK;IAClB,YAAY,KAAK;IACjB,SAAS;IACT;GACF,CAAC,GACD,OAAO,IAAI,mBAAmB;IAC5B,SAAS;IACT,GAAG;GACL,CAAC;EACH;EAEA,iBAAiB,UAAkB;GAC7B,aAAa,IAAI,QAAQ,MAC7B,aAAa,IAAI,QAAQ,GACzB,IAAI,MAAM,2BAA2B,EAAC,SAAQ,CAAC,GAC/C,OAAO,IAAI,gBAAgB,EAAC,SAAQ,CAAC;EACvC;EAEA,SAAS,WAAmB,UAAkB;GAE5C,AADA,IAAI,MAAM,oBAAoB;IAAC;IAAW;GAAQ,CAAC,GACnD,OAAO,IAAI,UAAU;IAAC;IAAW;GAAQ,CAAC;EAC5C;EAEA,aAAa;GACX,IAAM,kBAAkB,KAAK,OAAO,KAAK,IAAI,IAAI,aAAa,GAAI;GAclE,AAbA,IAAI,MAAM,4BAA4B;IACpC;IACA,WAAW,CAAC,GAAG,YAAY;IAC3B;GACF,CAAC,GACD,OAAO,IAAI,iBAAiB;IAC1B;IACA,WAAW,CAAC,GAAG,YAAY;GAC7B,CAAC,GAED,MAAM,MAAM,CAAC,CAAC,YAAY,CAE1B,CAAC,GACD,MAAM,IAAI;EACZ;EAEA,UAAU;GACR,MAAM,IAAI;EACZ;EAEA,IAAI,YAAiC;GACnC,OAAO;EACT;CACF;AACF;ACjMA,MAEM,SAAS,aAAa,WAAW,GAUjC,oCAAoB,IAAI,QAA0C,GAClE,+BAAe,IAAI,QAAqC,GACxD,+BAAe,IAAI,QAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BjD,SAAgB,cAAc,UAA0B,WAAyB;CAC/E,IAAM,cAAc,wBAAwB;CAC5C,IAAI,CAAC,aAAa;EAChB,OAAO,MAAM,mDAAmD,EAAC,UAAU,GAAI,CAAC;EAChF;CACF;CACA,IAAI,CAAC,WAAW;EACd,OAAO,MAAM,uCAAuC,EAAC,UAAU,GAAI,CAAC;EACpE;CACF;CACI,kBAAkB,IAAI,QAAQ,KAAK,aAAa,IAAI,QAAQ,MAGhE,aAAa,IAAI,QAAQ,GAEzB,OAAO,MAAM,0BAA0B;EAAC;EAAW;CAAW,CAAC,GAE/D,QAAQ,IAAI;;EAEV,OAAO,6BAAwB,CAAA,MAAA,MAAA,EAAA,CAAA;EAC/B,OAAO,6BAAoB,CAAA,MAAA,MAAA,EAAA,CAAA;CAC7B,CAAC,CAAC,CACC,KAAK,OAAO,CAAC,EAAC,0BAAyB,EAAC,aAAY,EAAC,qBAAoB;EACxE,IAAI,SAAS,WAAW,GAAG;GAEzB,AADA,aAAa,OAAO,QAAQ,GAC5B,OAAO,MAAM,8DAA8D;GAC3E;EACF;EAQA,IAAM,QAAQ,cAAc,QAAQ,CAAC,CAAC,WAAW;EAGjD,IAFA,OAAO,MAAM,oBAAoB;GAAC,cAAc,CAAC,CAAC;GAAO,UAAU;EAAI,CAAC,GAEpE,CAAC,UACH,OAAO,MAAM,wBAAwB,GA0BjC,CAAC,MAzBkB,IAAI,SAAkB,YAAY;GACvD,IAAI,SAAS,WAAW,GAAG,OAAO,QAAQ,EAAK;GAC/C,IAAM,UAAU,EAAC,mBAAmB,CAAC,EAAC,GAChC,QAAQ,SAAS,gBAAgB;IAErC,AADA,QAAQ,YAAY,GACpB,QAAQ,EAAK;GACf,CAAC,GAOG,WAAW,IACT,MAAM,cAAc,QAAQ,CAAC,CAAC,WAAW,WAAW,MAAM;IAC1D,YAAY,CAAC,MACjB,WAAW,IACX,OAAO,MAAM,qBAAqB,GAClC,MAAM,GACN,QAAQ,EAAI,GACZ,QAAQ,YAAY;GACtB,CAAC;GAED,AADA,QAAQ,oBAAoB,IAAI,YAAY,GACxC,YAAU,QAAQ,YAAY;EACpC,CAAC,KACgB,SAAS,WAAW,IAAG;GAEtC,AADA,aAAa,OAAO,QAAQ,GAC5B,OAAO,MAAM,2DAA2D;GACxE;EACF;EAGF,IAAM,UAAU,uBAAuB;GACrC,WAAW,SAAS;GACpB,iBAAiB,UAAU,UAAU,EAAC,YAAY,aAA6B,CAAC;GAChF;GACA;EACF,CAAC,GAEK,YAAY,MAAM,QAAQ,aAAa;EAE7C,IADA,OAAO,MAAM,0BAA0B,EAAC,UAAS,CAAC,GAC9C,CAAC,aAAa,SAAS,WAAW,GAAG;GAEvC,AADA,aAAa,OAAO,QAAQ,GAC5B,QAAQ,QAAQ;GAChB;EACF;EAGA,AADA,aAAa,OAAO,QAAQ,GAC5B,kBAAkB,IAAI,UAAU,OAAO;EAEvC,IAAM,WAAW,aAAa,IAAI,QAAQ;EAC1C,IAAI,UAAU;GACZ,OAAO,MAAM,2BAA2B,EAAC,OAAO,MAAM,KAAK,QAAQ,EAAC,CAAC;GACrE,KAAK,IAAM,YAAY,UACrB,QAAQ,iBAAiB,QAAQ;GAEnC,aAAa,OAAO,QAAQ;EAC9B;EAEA,IAAM,SAAS,SAAS,QAClB,cAAc,OAAO,OAAO,eAAgB,WAAW,OAAO,cAAc,aAC5E,aAAa,OAAO,MAAM,QAC5B,UACA,OAAO,QAAQ,MAAM,QACnB,WACA;EASN,AAPA,OAAO,KAAK,6BAA6B;GAAC;GAAW;GAAa;GAAY;EAAW,CAAC,GAC1F,QAAQ,kBAAkB;GACxB;GACA;GACA;EACF,CAAC,GAED,SAAS,gBAAgB;GAGvB,AAFA,QAAQ,WAAW,GACnB,kBAAkB,OAAO,QAAQ,GACjC,OAAO,MAAM,yBAAyB;EACxC,CAAC;CACH,CAAC,CAAC,CACD,OAAO,QAAQ;EAEd,AADA,aAAa,OAAO,QAAQ,GAC5B,OAAO,KAAK,yBAAyB,EAAC,OAAO,IAAG,CAAC;CACnD,CAAC;AACL;;;;;;;AAQA,SAAgB,oBAAoB,UAAwD;CAC1F,OAAO,kBAAkB,IAAI,QAAQ;AACvC;;;;;;;;AASA,SAAgB,iBAAiB,UAA0B,UAAwB;CACjF,IAAI,CAAC,wBAAwB,GAAG;CAEhC,IAAM,UAAU,YAAY,QAAQ;CACpC,IAAI,SAAS;EAEX,AADA,OAAO,MAAM,yBAAyB;GAAC;GAAU,UAAU;EAAI,CAAC,GAChE,QAAQ,iBAAiB,QAAQ;EACjC;CACF;CAEA,IAAM,OAAO,gBAAgB,QAAQ,GACjC,QAAQ,aAAa,IAAI,IAAI;CAQjC,AAPK,UACH,wBAAQ,IAAI,IAAI,GAChB,aAAa,IAAI,MAAM,KAAK,IAEzB,MAAM,IAAI,QAAQ,KACrB,OAAO,MAAM,2BAA2B;EAAC;EAAU,UAAU;CAAI,CAAC,GAEpE,MAAM,IAAI,QAAQ;AACpB;AAEA,SAAS,YAAY,UAAwD;CAC3E,OAAO,kBAAkB,IAAI,QAAQ;AACvC;AAEA,SAAS,gBAAgB,UAA0C;CACjE,OAAO;AACT;ACzNA,MAIM,cAAc;;;;;AAMpB,SAAS,gBAAgB,OAAoC;CAC3D,OAAc,UAAU,UAAe,MAAM,KAAK,CAAC,CAAC,WAAW,GAAc;AAC/E;;;;;AAMA,SAAS,cAAc,OAAoC;CACzD,OAAc,UAAU,UAAe,MAAM,KAAK,CAAC,CAAC,SAAS,GAAc;AAC7E;;;;;AAMA,SAAS,kBAAkB,OAAoC;CAE7D,OAAO,CAAC,CAAC,SAAS,MAAM,UAAU,KAAK,MAAM,WAAW,IAAG,KAAK,MAAM,SAAS,IAAG;AACpF;;;;;;;;;;;;;;AAeA,SAAgB,uBAAuB,OAAuB;CAE5D,IAAM,eAAe,MAAM,KAAK;CAChC,IAAI,CAAC,cACH,OAAO;CAIT,IAAM,SAAS,aAAa,MAAM,WAAW,KAAK,CAAC,GAI7C,gBADiB,CAAC,GAAG,MAAM,CAAC,CAAC,QACA,CAAC,CAAC,WAClC,UAAkB,CAAC,gBAAgB,KAAK,KAAK,CAAC,kBAAkB,KAAK,CACxE,GACM,6BAA6B,kBAAkB,KAAK,KAAK,OAAO,SAAS,IAAI,eAG7E,wBAAwB,OAAO,6BAE/B,kBAAkB,CAAC,GAAG,MAAM;CAmBlC,OAhBI,0BAA0B,KAAA,KAAa,CAAC,cAAc,qBAAqB,KAE7E,gBAAgB,OACd,4BACA,GACA,GAAG,wBACL,GAUK,0BANgB,gBAAgB,KAAK,GAGT,CAAC,CAAC,QAAQ,MAAM,MAGN,EAAE;AACjD"}
@@ -1,4 +1,4 @@
1
- import { s as DocumentResource, t as SanityInstance } from "../createSanityInstance-DUI1bGIg.js";
1
+ import { s as DocumentResource, t as SanityInstance } from "../createSanityInstance-DCePpBYW.js";
2
2
  import { SanityClient } from "@sanity/client";
3
3
  import { Observable } from "rxjs";
4
4
  /** @alpha */
@@ -1,4 +1,4 @@
1
- import { r as getClientState } from "../clientStore-BtE2-q2i.js";
1
+ import { r as getClientState } from "../clientStore-gUALQ0qW.js";
2
2
  import "@sanity/client";
3
3
  import { from, switchMap } from "rxjs";
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { Ei as BoundStoreAction, Ti as StateSource } from "../authStore-DKFX8fn7.js";
1
+ import { Ti as BoundStoreAction, wi as StateSource } from "../authStore-C-OEkGaM.js";
2
2
  import { ChannelInput, ChannelInstance, Controller, Message, Node, NodeInput, Status } from "@sanity/comlink";
3
3
  /**
4
4
  * Message sent from a containing app to an iframe
@@ -1,6 +1,5 @@
1
- import { a as defineStore, i as bindActionGlobally } from "../createStateSourceAction-BOKtqFNm.js";
2
- import { t as isDeepEqual } from "../object-CxXlSVg7.js";
3
- import { n as getOrCreateNode, r as releaseNode, t as getNodeState } from "../getNodeState-CR3__B2D.js";
1
+ import { c as bindActionGlobally, l as defineStore, t as isDeepEqual } from "../object-BwynGPRZ.js";
2
+ import { n as getOrCreateNode, r as releaseNode, t as getNodeState } from "../getNodeState-E0hjqFOo.js";
4
3
  import { createController } from "@sanity/comlink";
5
4
  /**
6
5
  * Calls the destroy method on the controller and resets the controller state.
@@ -1 +1 @@
1
- {"version":3,"file":"comlink.js","names":["destroyController","getOrCreateChannel","getOrCreateController","releaseChannel","unboundDestroyController","unboundGetOrCreateChannel","unboundGetOrCreateController","unboundReleaseChannel"],"sources":["../../src/comlink/controller/actions/destroyController.ts","../../src/comlink/controller/actions/getOrCreateChannel.ts","../../src/comlink/controller/actions/getOrCreateController.ts","../../src/comlink/controller/actions/releaseChannel.ts","../../src/comlink/controller/comlinkControllerStore.ts"],"sourcesContent":["import {type StoreContext} from '../../../store/defineStore'\nimport {type ComlinkControllerState} from '../comlinkControllerStore'\n\n/**\n * Calls the destroy method on the controller and resets the controller state.\n * @public\n */\nexport const destroyController = ({state}: StoreContext<ComlinkControllerState>): void => {\n const {controller} = state.get()\n\n if (controller) {\n controller.destroy()\n state.set('destroyController', {\n controller: null,\n channels: new Map(),\n })\n }\n}\n","import {type ChannelInput, type ChannelInstance} from '@sanity/comlink'\n\nimport {type StoreContext} from '../../../store/defineStore'\nimport {isDeepEqual} from '../../../utils/object'\nimport {type FrameMessage, type WindowMessage} from '../../types'\nimport {type ComlinkControllerState} from '../comlinkControllerStore'\n\n/**\n * Retrieve or create a channel to be used for communication between\n * an application and the controller.\n * @public\n */\nexport const getOrCreateChannel = (\n {state}: StoreContext<ComlinkControllerState>,\n options: ChannelInput,\n): ChannelInstance<FrameMessage, WindowMessage> => {\n const controller = state.get().controller\n\n if (!controller) {\n throw new Error('Controller must be initialized before using or creating channels')\n }\n\n const channels = state.get().channels\n const existing = channels.get(options.name)\n\n // limit channels to one per name\n if (existing) {\n if (!isDeepEqual(existing.options, options)) {\n throw new Error(`Channel \"${options.name}\" already exists with different options`)\n }\n\n state.set('incrementChannelRefCount', {\n channels: new Map(channels).set(options.name, {\n ...existing,\n refCount: existing.refCount + 1,\n }),\n })\n existing.channel.start()\n return existing.channel\n }\n\n const channel = controller.createChannel(options)\n channel.start()\n state.set('createChannel', {\n channels: new Map(channels).set(options.name, {\n channel,\n options,\n refCount: 1,\n }),\n })\n\n return channel\n}\n","import {type Controller, createController} from '@sanity/comlink'\n\nimport {type StoreContext} from '../../../store/defineStore'\nimport {type ComlinkControllerState} from '../comlinkControllerStore'\nimport {destroyController} from './destroyController'\n\n/**\n * Initializes or fetches a controller to handle communication\n * between an application and iframes.\n * @public\n */\nexport const getOrCreateController = (\n {state, instance}: StoreContext<ComlinkControllerState>,\n targetOrigin: string,\n): Controller => {\n const {controller, controllerOrigin} = state.get()\n if (controller && controllerOrigin === targetOrigin) {\n return controller\n }\n\n // if the target origin has changed, we'll create a new controller,\n // but need to clean up first\n if (controller) {\n destroyController({state, instance, key: undefined})\n }\n\n const newController = createController({targetOrigin})\n state.set('initializeController', {\n controllerOrigin: targetOrigin,\n controller: newController,\n })\n\n return newController\n}\n","import {type StoreContext} from '../../../store/defineStore'\nimport {type ComlinkControllerState} from '../comlinkControllerStore'\n\n/**\n * Signals to the store that the consumer has stopped using the channel\n * @public\n */\nexport const releaseChannel = (\n {state}: StoreContext<ComlinkControllerState>,\n name: string,\n): void => {\n const channels = state.get().channels\n const channelEntry = channels.get(name)\n\n if (channelEntry) {\n const newRefCount = channelEntry.refCount === 0 ? 0 : channelEntry.refCount - 1\n\n if (newRefCount === 0) {\n channelEntry.channel.stop()\n channels.delete(name)\n state.set('releaseChannel', {channels: new Map(channels)})\n } else {\n state.set('releaseChannel', {\n channels: new Map(channels).set(name, {\n ...channelEntry,\n refCount: newRefCount,\n }),\n })\n }\n }\n}\n","import {type ChannelInput, type ChannelInstance, type Controller} from '@sanity/comlink'\n\nimport {bindActionGlobally} from '../../store/createActionBinder'\nimport {defineStore} from '../../store/defineStore'\nimport {type FrameMessage, type WindowMessage} from '../types'\nimport {destroyController as unboundDestroyController} from './actions/destroyController'\nimport {getOrCreateChannel as unboundGetOrCreateChannel} from './actions/getOrCreateChannel'\nimport {getOrCreateController as unboundGetOrCreateController} from './actions/getOrCreateController'\nimport {releaseChannel as unboundReleaseChannel} from './actions/releaseChannel'\n\n/**\n * Individual channel with its relevant options\n * @public\n */\nexport interface ChannelEntry {\n channel: ChannelInstance<FrameMessage, WindowMessage>\n // we store options to ensure that channels remain as unique / consistent as possible\n options: ChannelInput\n // we store refCount to ensure channels remain open only as long as they are in use\n refCount: number\n}\n\n/**\n * Internal state tracking comlink connections\n * @public\n */\nexport interface ComlinkControllerState {\n controller: Controller | null\n controllerOrigin: string | null\n channels: Map<string, ChannelEntry>\n}\n\nexport const comlinkControllerStore = defineStore<ComlinkControllerState>({\n name: 'connectionStore',\n getInitialState: () => {\n const initialState = {\n controller: null,\n controllerOrigin: null,\n channels: new Map(),\n }\n return initialState\n },\n initialize({instance}) {\n return () => {\n // destroying controller also destroys channels\n destroyController(instance)\n }\n },\n})\n\n/**\n * Calls the destroy method on the controller and resets the controller state.\n * @public\n */\nexport const destroyController = bindActionGlobally(\n comlinkControllerStore,\n unboundDestroyController,\n)\n\n/**\n * Retrieve or create a channel to be used for communication between\n * an application and the controller.\n * @public\n */\nexport const getOrCreateChannel = bindActionGlobally(\n comlinkControllerStore,\n unboundGetOrCreateChannel,\n)\n\n/**\n * Initializes or fetches a controller to handle communication\n * between an application and iframes.\n * @public\n */\nexport const getOrCreateController = bindActionGlobally(\n comlinkControllerStore,\n unboundGetOrCreateController,\n)\n\n/**\n * Signals to the store that the consumer has stopped using the channel\n * @public\n */\nexport const releaseChannel = bindActionGlobally(comlinkControllerStore, unboundReleaseChannel)\n"],"mappings":";;;;;;;;AAOA,MAAaA,uBAAqB,EAAC,YAAuD;CACxF,IAAM,EAAC,eAAc,MAAM,IAAI;CAE/B,AAAI,eACF,WAAW,QAAQ,GACnB,MAAM,IAAI,qBAAqB;EAC7B,YAAY;EACZ,0BAAU,IAAI,IAAI;CACpB,CAAC;AAEL,GCLaC,wBACX,EAAC,SACD,YACiD;CACjD,IAAM,aAAa,MAAM,IAAI,CAAC,CAAC;CAE/B,IAAI,CAAC,YACH,MAAU,MAAM,kEAAkE;CAGpF,IAAM,WAAW,MAAM,IAAI,CAAC,CAAC,UACvB,WAAW,SAAS,IAAI,QAAQ,IAAI;CAG1C,IAAI,UAAU;EACZ,IAAI,CAAC,YAAY,SAAS,SAAS,OAAO,GACxC,MAAU,MAAM,YAAY,QAAQ,KAAK,wCAAwC;EAUnF,OAPA,MAAM,IAAI,4BAA4B,EACpC,UAAU,IAAI,IAAI,QAAQ,CAAC,CAAC,IAAI,QAAQ,MAAM;GAC5C,GAAG;GACH,UAAU,SAAS,WAAW;EAChC,CAAC,EACH,CAAC,GACD,SAAS,QAAQ,MAAM,GAChB,SAAS;CAClB;CAEA,IAAM,UAAU,WAAW,cAAc,OAAO;CAUhD,OATA,QAAQ,MAAM,GACd,MAAM,IAAI,iBAAiB,EACzB,UAAU,IAAI,IAAI,QAAQ,CAAC,CAAC,IAAI,QAAQ,MAAM;EAC5C;EACA;EACA,UAAU;CACZ,CAAC,EACH,CAAC,GAEM;AACT,GCzCaC,2BACX,EAAC,OAAO,YACR,iBACe;CACf,IAAM,EAAC,YAAY,qBAAoB,MAAM,IAAI;CACjD,IAAI,cAAc,qBAAqB,cACrC,OAAO;CAKT,AAAI,cACF,oBAAkB;EAAC;EAAO;EAAU,KAAK,KAAA;CAAS,CAAC;CAGrD,IAAM,gBAAgB,iBAAiB,EAAC,aAAY,CAAC;CAMrD,OALA,MAAM,IAAI,wBAAwB;EAChC,kBAAkB;EAClB,YAAY;CACd,CAAC,GAEM;AACT,GC1BaC,oBACX,EAAC,SACD,SACS;CACT,IAAM,WAAW,MAAM,IAAI,CAAC,CAAC,UACvB,eAAe,SAAS,IAAI,IAAI;CAEtC,IAAI,cAAc;EAChB,IAAM,cAAc,aAAa,aAAa,IAAI,IAAI,aAAa,WAAW;EAE9E,AAAI,gBAAgB,KAClB,aAAa,QAAQ,KAAK,GAC1B,SAAS,OAAO,IAAI,GACpB,MAAM,IAAI,kBAAkB,EAAC,UAAU,IAAI,IAAI,QAAQ,EAAC,CAAC,KAEzD,MAAM,IAAI,kBAAkB,EAC1B,UAAU,IAAI,IAAI,QAAQ,CAAC,CAAC,IAAI,MAAM;GACpC,GAAG;GACH,UAAU;EACZ,CAAC,EACH,CAAC;CAEL;AACF,GCEa,yBAAyB,YAAoC;CACxE,MAAM;CACN,wBAMS;EAJL,YAAY;EACZ,kBAAkB;EAClB,0BAAU,IAAI,IAAI;CAEF;CAEpB,WAAW,EAAC,YAAW;EACrB,aAAa;GAEX,kBAAkB,QAAQ;EAC5B;CACF;AACF,CAAC,GAMY,oBAAoB,mBAC/B,wBACAC,mBACF,GAOa,qBAAqB,mBAChC,wBACAC,oBACF,GAOa,wBAAwB,mBACnC,wBACAC,uBACF,GAMa,iBAAiB,mBAAmB,wBAAwBC,gBAAqB"}
1
+ {"version":3,"file":"comlink.js","names":["destroyController","getOrCreateChannel","getOrCreateController","releaseChannel","unboundDestroyController","unboundGetOrCreateChannel","unboundGetOrCreateController","unboundReleaseChannel"],"sources":["../../src/comlink/controller/actions/destroyController.ts","../../src/comlink/controller/actions/getOrCreateChannel.ts","../../src/comlink/controller/actions/getOrCreateController.ts","../../src/comlink/controller/actions/releaseChannel.ts","../../src/comlink/controller/comlinkControllerStore.ts"],"sourcesContent":["import {type StoreContext} from '../../../store/defineStore'\nimport {type ComlinkControllerState} from '../comlinkControllerStore'\n\n/**\n * Calls the destroy method on the controller and resets the controller state.\n * @public\n */\nexport const destroyController = ({state}: StoreContext<ComlinkControllerState>): void => {\n const {controller} = state.get()\n\n if (controller) {\n controller.destroy()\n state.set('destroyController', {\n controller: null,\n channels: new Map(),\n })\n }\n}\n","import {type ChannelInput, type ChannelInstance} from '@sanity/comlink'\n\nimport {type StoreContext} from '../../../store/defineStore'\nimport {isDeepEqual} from '../../../utils/object'\nimport {type FrameMessage, type WindowMessage} from '../../types'\nimport {type ComlinkControllerState} from '../comlinkControllerStore'\n\n/**\n * Retrieve or create a channel to be used for communication between\n * an application and the controller.\n * @public\n */\nexport const getOrCreateChannel = (\n {state}: StoreContext<ComlinkControllerState>,\n options: ChannelInput,\n): ChannelInstance<FrameMessage, WindowMessage> => {\n const controller = state.get().controller\n\n if (!controller) {\n throw new Error('Controller must be initialized before using or creating channels')\n }\n\n const channels = state.get().channels\n const existing = channels.get(options.name)\n\n // limit channels to one per name\n if (existing) {\n if (!isDeepEqual(existing.options, options)) {\n throw new Error(`Channel \"${options.name}\" already exists with different options`)\n }\n\n state.set('incrementChannelRefCount', {\n channels: new Map(channels).set(options.name, {\n ...existing,\n refCount: existing.refCount + 1,\n }),\n })\n existing.channel.start()\n return existing.channel\n }\n\n const channel = controller.createChannel(options)\n channel.start()\n state.set('createChannel', {\n channels: new Map(channels).set(options.name, {\n channel,\n options,\n refCount: 1,\n }),\n })\n\n return channel\n}\n","import {type Controller, createController} from '@sanity/comlink'\n\nimport {type StoreContext} from '../../../store/defineStore'\nimport {type ComlinkControllerState} from '../comlinkControllerStore'\nimport {destroyController} from './destroyController'\n\n/**\n * Initializes or fetches a controller to handle communication\n * between an application and iframes.\n * @public\n */\nexport const getOrCreateController = (\n {state, instance}: StoreContext<ComlinkControllerState>,\n targetOrigin: string,\n): Controller => {\n const {controller, controllerOrigin} = state.get()\n if (controller && controllerOrigin === targetOrigin) {\n return controller\n }\n\n // if the target origin has changed, we'll create a new controller,\n // but need to clean up first\n if (controller) {\n destroyController({state, instance, key: undefined})\n }\n\n const newController = createController({targetOrigin})\n state.set('initializeController', {\n controllerOrigin: targetOrigin,\n controller: newController,\n })\n\n return newController\n}\n","import {type StoreContext} from '../../../store/defineStore'\nimport {type ComlinkControllerState} from '../comlinkControllerStore'\n\n/**\n * Signals to the store that the consumer has stopped using the channel\n * @public\n */\nexport const releaseChannel = (\n {state}: StoreContext<ComlinkControllerState>,\n name: string,\n): void => {\n const channels = state.get().channels\n const channelEntry = channels.get(name)\n\n if (channelEntry) {\n const newRefCount = channelEntry.refCount === 0 ? 0 : channelEntry.refCount - 1\n\n if (newRefCount === 0) {\n channelEntry.channel.stop()\n channels.delete(name)\n state.set('releaseChannel', {channels: new Map(channels)})\n } else {\n state.set('releaseChannel', {\n channels: new Map(channels).set(name, {\n ...channelEntry,\n refCount: newRefCount,\n }),\n })\n }\n }\n}\n","import {type ChannelInput, type ChannelInstance, type Controller} from '@sanity/comlink'\n\nimport {bindActionGlobally} from '../../store/createActionBinder'\nimport {defineStore} from '../../store/defineStore'\nimport {type FrameMessage, type WindowMessage} from '../types'\nimport {destroyController as unboundDestroyController} from './actions/destroyController'\nimport {getOrCreateChannel as unboundGetOrCreateChannel} from './actions/getOrCreateChannel'\nimport {getOrCreateController as unboundGetOrCreateController} from './actions/getOrCreateController'\nimport {releaseChannel as unboundReleaseChannel} from './actions/releaseChannel'\n\n/**\n * Individual channel with its relevant options\n * @public\n */\nexport interface ChannelEntry {\n channel: ChannelInstance<FrameMessage, WindowMessage>\n // we store options to ensure that channels remain as unique / consistent as possible\n options: ChannelInput\n // we store refCount to ensure channels remain open only as long as they are in use\n refCount: number\n}\n\n/**\n * Internal state tracking comlink connections\n * @public\n */\nexport interface ComlinkControllerState {\n controller: Controller | null\n controllerOrigin: string | null\n channels: Map<string, ChannelEntry>\n}\n\nexport const comlinkControllerStore = defineStore<ComlinkControllerState>({\n name: 'connectionStore',\n getInitialState: () => {\n const initialState = {\n controller: null,\n controllerOrigin: null,\n channels: new Map(),\n }\n return initialState\n },\n initialize({instance}) {\n return () => {\n // destroying controller also destroys channels\n destroyController(instance)\n }\n },\n})\n\n/**\n * Calls the destroy method on the controller and resets the controller state.\n * @public\n */\nexport const destroyController = bindActionGlobally(\n comlinkControllerStore,\n unboundDestroyController,\n)\n\n/**\n * Retrieve or create a channel to be used for communication between\n * an application and the controller.\n * @public\n */\nexport const getOrCreateChannel = bindActionGlobally(\n comlinkControllerStore,\n unboundGetOrCreateChannel,\n)\n\n/**\n * Initializes or fetches a controller to handle communication\n * between an application and iframes.\n * @public\n */\nexport const getOrCreateController = bindActionGlobally(\n comlinkControllerStore,\n unboundGetOrCreateController,\n)\n\n/**\n * Signals to the store that the consumer has stopped using the channel\n * @public\n */\nexport const releaseChannel = bindActionGlobally(comlinkControllerStore, unboundReleaseChannel)\n"],"mappings":";;;;;;;AAOA,MAAaA,uBAAqB,EAAC,YAAuD;CACxF,IAAM,EAAC,eAAc,MAAM,IAAI;CAE/B,AAAI,eACF,WAAW,QAAQ,GACnB,MAAM,IAAI,qBAAqB;EAC7B,YAAY;EACZ,0BAAU,IAAI,IAAI;CACpB,CAAC;AAEL,GCLaC,wBACX,EAAC,SACD,YACiD;CACjD,IAAM,aAAa,MAAM,IAAI,CAAC,CAAC;CAE/B,IAAI,CAAC,YACH,MAAU,MAAM,kEAAkE;CAGpF,IAAM,WAAW,MAAM,IAAI,CAAC,CAAC,UACvB,WAAW,SAAS,IAAI,QAAQ,IAAI;CAG1C,IAAI,UAAU;EACZ,IAAI,CAAC,YAAY,SAAS,SAAS,OAAO,GACxC,MAAU,MAAM,YAAY,QAAQ,KAAK,wCAAwC;EAUnF,OAPA,MAAM,IAAI,4BAA4B,EACpC,UAAU,IAAI,IAAI,QAAQ,CAAC,CAAC,IAAI,QAAQ,MAAM;GAC5C,GAAG;GACH,UAAU,SAAS,WAAW;EAChC,CAAC,EACH,CAAC,GACD,SAAS,QAAQ,MAAM,GAChB,SAAS;CAClB;CAEA,IAAM,UAAU,WAAW,cAAc,OAAO;CAUhD,OATA,QAAQ,MAAM,GACd,MAAM,IAAI,iBAAiB,EACzB,UAAU,IAAI,IAAI,QAAQ,CAAC,CAAC,IAAI,QAAQ,MAAM;EAC5C;EACA;EACA,UAAU;CACZ,CAAC,EACH,CAAC,GAEM;AACT,GCzCaC,2BACX,EAAC,OAAO,YACR,iBACe;CACf,IAAM,EAAC,YAAY,qBAAoB,MAAM,IAAI;CACjD,IAAI,cAAc,qBAAqB,cACrC,OAAO;CAKT,AAAI,cACF,oBAAkB;EAAC;EAAO;EAAU,KAAK,KAAA;CAAS,CAAC;CAGrD,IAAM,gBAAgB,iBAAiB,EAAC,aAAY,CAAC;CAMrD,OALA,MAAM,IAAI,wBAAwB;EAChC,kBAAkB;EAClB,YAAY;CACd,CAAC,GAEM;AACT,GC1BaC,oBACX,EAAC,SACD,SACS;CACT,IAAM,WAAW,MAAM,IAAI,CAAC,CAAC,UACvB,eAAe,SAAS,IAAI,IAAI;CAEtC,IAAI,cAAc;EAChB,IAAM,cAAc,aAAa,aAAa,IAAI,IAAI,aAAa,WAAW;EAE9E,AAAI,gBAAgB,KAClB,aAAa,QAAQ,KAAK,GAC1B,SAAS,OAAO,IAAI,GACpB,MAAM,IAAI,kBAAkB,EAAC,UAAU,IAAI,IAAI,QAAQ,EAAC,CAAC,KAEzD,MAAM,IAAI,kBAAkB,EAC1B,UAAU,IAAI,IAAI,QAAQ,CAAC,CAAC,IAAI,MAAM;GACpC,GAAG;GACH,UAAU;EACZ,CAAC,EACH,CAAC;CAEL;AACF,GCEa,yBAAyB,YAAoC;CACxE,MAAM;CACN,wBAMS;EAJL,YAAY;EACZ,kBAAkB;EAClB,0BAAU,IAAI,IAAI;CAEF;CAEpB,WAAW,EAAC,YAAW;EACrB,aAAa;GAEX,kBAAkB,QAAQ;EAC5B;CACF;AACF,CAAC,GAMY,oBAAoB,mBAC/B,wBACAC,mBACF,GAOa,qBAAqB,mBAChC,wBACAC,oBACF,GAOa,wBAAwB,mBACnC,wBACAC,uBACF,GAMa,iBAAiB,mBAAmB,wBAAwBC,gBAAqB"}
@@ -1,5 +1,5 @@
1
- import { b as AuthConfig, c as DocumentTypeHandle, d as ProjectHandle, f as ReleaseHandle, i as DatasetHandle, o as DocumentHandle, s as DocumentResource, t as SanityInstance, u as PerspectiveHandle, x as AuthProvider } from "./createSanityInstance-DUI1bGIg.js";
2
- import { ClientConfig, ClientPerspective, ListenEvent, MultipleMutationResult, ReleaseDocument, ReleaseDocument as ReleaseDocument$1, ResponseQueryOptions, SanityClient, SanityDocument, SanityProject } from "@sanity/client";
1
+ import { b as AuthConfig, c as DocumentTypeHandle, d as ProjectHandle, f as ReleaseHandle, i as DatasetHandle, o as DocumentHandle, s as DocumentResource, t as SanityInstance, u as PerspectiveHandle, x as AuthProvider } from "./createSanityInstance-DCePpBYW.js";
2
+ import { ClientConfig, ClientPerspective, DatasetsResponse, ListenEvent, MultipleMutationResult, ReleaseDocument, ReleaseDocument as ReleaseDocument$1, ResponseQueryOptions, SanityClient, SanityDocument, SanityProject } from "@sanity/client";
3
3
  import { Observable, Subject } from "rxjs";
4
4
  import { CurrentUser, CurrentUser as CurrentUser$1, Mutation, PatchOperations, Path, PortableTextBlock, Role, SanityDocument as SanityDocument$1, SanityDocument as SanityDocument$3, SanityDocumentLike } from "@sanity/types";
5
5
  import "zustand/middleware";
@@ -1364,10 +1364,13 @@ interface Logger {
1364
1364
  * @public
1365
1365
  */
1366
1366
  declare function configureLogging(config: LoggerConfig): void;
1367
- /** @public */
1368
- declare const getDatasetsState: BoundStoreAction<FetcherStoreState<[options?: ProjectHandle<string> | undefined], import("@sanity/client").DatasetsResponse>, [options?: ProjectHandle<string> | undefined], StateSource<import("@sanity/client").DatasetsResponse | undefined>>;
1369
- /** @public */
1370
- declare const resolveDatasets: BoundStoreAction<FetcherStoreState<[options?: ProjectHandle<string> | undefined], import("@sanity/client").DatasetsResponse>, [options?: ProjectHandle<string> | undefined], Promise<import("@sanity/client").DatasetsResponse>>;
1367
+ /**
1368
+ * Fetcher for a project's datasets (`GET /datasets`), on the shared fetcher
1369
+ * cache.
1370
+ *
1371
+ * @internal
1372
+ */
1373
+ declare const datasets: Fetcher<[options?: ProjectHandle<string> | undefined], DatasetsResponse>;
1371
1374
  /**
1372
1375
  * Represents an action to create a new document.
1373
1376
  * Specifies the document type and optionally a document ID (which will be treated as the published ID).
@@ -2107,21 +2110,29 @@ interface FavoriteDocumentContext extends DocumentHandle {
2107
2110
  schemaName?: string;
2108
2111
  }
2109
2112
  /**
2110
- * Gets a StateSource for the favorite status of a document.
2111
- * @param instance - The Sanity instance.
2112
- * @param context - The document context including ID, type, and resource information.
2113
- * @returns A StateSource emitting `{ isFavorited: boolean }`.
2114
- * @public
2113
+ * Fetcher for a document's favorite status, read from the dashboard over
2114
+ * comlink, on the shared fetcher cache.
2115
+ *
2116
+ * @internal
2115
2117
  */
2116
- declare const getFavoritesState: BoundStoreAction<FetcherStoreState<[FavoriteDocumentContext], FavoriteStatusResponse>, [FavoriteDocumentContext], StateSource<FavoriteStatusResponse | undefined>>;
2118
+ declare const favorites: Fetcher<[context: FavoriteDocumentContext], FavoriteStatusResponse>;
2117
2119
  /**
2118
- * Resolves the favorite status for a document.
2119
- * @param instance - The Sanity instance.
2120
- * @param context - The document context including ID, type, and resource information.
2121
- * @returns A Promise resolving to `{ isFavorited: boolean }`.
2120
+ * Input for {@link setFavorite}: the document context plus the desired state.
2121
+ *
2122
2122
  * @public
2123
2123
  */
2124
- declare const resolveFavoritesState: BoundStoreAction<FetcherStoreState<[FavoriteDocumentContext], FavoriteStatusResponse>, [FavoriteDocumentContext], Promise<FavoriteStatusResponse>>;
2124
+ type SetFavoriteInput = FavoriteDocumentContext & {
2125
+ /** The favorite state to move to: `true` to favorite, `false` to unfavorite. */
2126
+ isFavorited: boolean;
2127
+ };
2128
+ /**
2129
+ * Sets a document's favorite state over comlink, then invalidates the cached
2130
+ * {@link favorites} status for that document so active readers reconverge on
2131
+ * server truth. The write-side counterpart to {@link favorites}.
2132
+ *
2133
+ * @internal
2134
+ */
2135
+ declare const setFavorite: (instance: SanityInstance, input: SetFavoriteInput) => Promise<MutationResult<FavoriteStatusResponse>>;
2125
2136
  /**
2126
2137
  * Related data the Installations API can embed in a response. Each token adds
2127
2138
  * a top-level field to the {@link Installation} item.
@@ -3006,31 +3017,6 @@ declare const getUserState: BoundStoreAction<UsersStoreState, [GetUserOptions],
3006
3017
  * @beta
3007
3018
  */
3008
3019
  declare const resolveUser: BoundStoreAction<UsersStoreState, [ResolveUserOptions], Promise<SanityUser>>;
3009
- interface StoreEntry<TParams extends unknown[], TData> {
3010
- params: TParams;
3011
- instance: SanityInstance;
3012
- key: string;
3013
- data?: TData;
3014
- error?: unknown;
3015
- subscriptions: string[];
3016
- lastFetchInitiatedAt?: string;
3017
- }
3018
- /**
3019
- * Internal helper type
3020
- * @public
3021
- */
3022
- interface FetcherStoreState<TParams extends unknown[], TData> {
3023
- stateByParams: { [TSerializedKey in string]?: StoreEntry<TParams, TData>; };
3024
- error?: unknown;
3025
- }
3026
- /**
3027
- * Internal helper type
3028
- * @public
3029
- */
3030
- interface FetcherStore<TParams extends unknown[], TData> {
3031
- getState: BoundStoreAction<FetcherStoreState<TParams, TData>, TParams, StateSource<TData | undefined>>;
3032
- resolveState: BoundStoreAction<FetcherStoreState<TParams, TData>, TParams, Promise<TData>>;
3033
- }
3034
3020
  /**
3035
3021
  * @public
3036
3022
  * Extracts the project ID from a CorsOriginError message.
@@ -3175,5 +3161,5 @@ declare const getIsInDashboardState: BoundStoreAction<AuthStoreState, [], StateS
3175
3161
  * @internal
3176
3162
  */
3177
3163
  declare const setAuthToken: BoundStoreAction<AuthStoreState, [token: string | null], void>;
3178
- export { ProjectOptions as $, unpublishDocument as $n, ApplicationInclude as $r, ApplyDocumentActionsOptions as $t, getUserState as A, DocumentAction as An, setCommentStatus as Ar, Organizations as At, getQueryKey as B, UnscheduleReleaseAction as Bn, ClientOptions as Br, InstallationActiveConfig as Bt, slicePath$1 as C, defineMutation as Ci, Action as Cn, RemoveCommentOptions as Cr, ResolveUserOptions as Ct, getCorsErrorProjectId as D, DeleteDocumentAction as Dn, createComment as Dr, UserProfile as Dt, isImportError as E, BoundStoreAction as Ei, CreateReleaseAction as En, UpdateCommentOptions as Er, SanityUserResponse as Et, getPerspectiveState as F, PublishReleaseAction as Fn, CommentReaction as Fr, OrganizationMember as Ft, projects as G, deleteRelease as Gn, handleAuthCallback as Gr, InstallationsResponse as Gt, parseQueryKey as H, createDocument as Hn, getClient as Hr, InstallationInclude as Ht, ReleaseState as I, ReleaseAction as In, CommentStatus as Ir, OrganizationOptions as It, Project as J, editRelease as Jn, AuthStateType as Jr, FavoriteStatusResponse as Jt, resolveProjection as K, discardDocument as Kn, observeOrganizationVerificationState as Kr, installation as Kt, getActiveReleasesState as L, ScheduleReleaseAction as Ln, CommentTextSelection as Lr, organization as Lt, loadMoreUsers as M, EditDocumentOptions as Mn, Comment as Mr, organizations as Mt, resolveUser as N, EditReleaseAction as Nn, CommentLocalState as Nr, Organization as Nt, FetcherStore as O, DeleteReleaseAction as On, removeComment as Or, UsersGroupState as Ot, resolveUsers as P, PublishDocumentAction as Pn, CommentMessage as Pr, OrganizationBase as Pt, ProjectMetadata as Q, unarchiveRelease as Qn, ApplicationDeployment as Qr, ActionsResult as Qt, getAllReleasesState as R, UnarchiveReleaseAction as Rn, CommentTextSelectionItem as Rr, Installation as Rt, jsonMatch$1 as S, defineFetcher as Si, JsonMatch as Sn, CreateCommentOptions as Sr, Membership as St, CORE_SDK_VERSION as T, StateSource as Ti, CreateDocumentAction as Tn, SetCommentStatusOptions as Tr, SanityUser as Tt, resolveQuery as U, createRelease as Un, getClientState as Ur, InstallationInterface as Ut, getQueryState as V, archiveRelease as Vn, ClientStoreState as Vr, InstallationBase as Vt, ProjectsOptions as W, deleteDocument as Wn, logout as Wr, InstallationsOptions as Wt, ProjectMember as X, publishRelease as Xn, ApplicationAccess as Xr, resolveFavoritesState as Xt, ProjectBase as Y, publishDocument as Yn, Application as Yr, getFavoritesState as Yt, ProjectMemberRole as Z, scheduleRelease as Zn, ApplicationBase as Zr, getReleaseDocumentId as Zt, SanityDocument$3 as _, Fetcher as _i, resolveDocument as _n, getCommentsOptionsKey as _r, StateEvent as _t, LoggedOutAuthState as a, ApplicationsResponse as ai, DocumentEditedEvent as an, LogContext as ar, getDocumentPresence as at, getPathDepth as b, MutationDefinition as bi, DocumentPermissionsResult as bn, resolveCommentThreads as br, GetUserOptions as bt, getCurrentUserState as c, UpdateApplicationInput as ci, DocumentRemotePatchesEvent as cn, Logger as cr, DisconnectEvent as ct, getLoginUrlState as d, deleteApplication as di, TransactionAcceptedEvent as dn, createDocumentHandle as dr, PresenceLocation as dt, ApplicationInterface as ei, applyDocumentActions as en, unscheduleRelease as er, project as et, getTokenState as f, updateApplication as fi, TransactionRevertedEvent as fn, createDocumentTypeHandle as fr, PresencePerspectiveOptions as ft, Role as g, CacheWriter as gi, getPermissionsState as gn, getCommentThreadsState as gr, RollCallEvent as gt, ReleaseDocument$1 as h, CacheTag as hi, getDocumentSyncStatus as hn, ResolveCommentsOptions as hr, ReportPresenceOptions as ht, LoggedInAuthState as i, ApplicationsOptions as ii, DocumentDiscardedEvent as in, InstanceContext as ir, ProjectionValuePending as it, getUsersState as j, EditDocumentAction as jn, updateComment as jr, OrganizationsOptions as jt, FetcherStoreState as k, DiscardDocumentAction as kn, replyToComment as kr, UsersStoreState as kt, getDashboardOrganizationId as l, application as li, DocumentTransactionSubmissionResult as ln, LoggerConfig as lr, DocumentPresence as lt, CurrentUser$1 as m, checkPermissions as mi, getDocumentState as mn, CommentsOptions as mr, PresenceSelectionPoint as mt, AuthStoreState as n, ApplicationVisibility as ni, DocumentCreatedEvent as nn, resolveDatasets as nr, PreviewQueryResult as nt, LoggingInAuthState as o, DeleteApplicationInput as oi, DocumentEvent as on, LogLevel as or, getPresence as ot, setAuthToken as p, AccessResourceType as pi, DocumentOptions as pn, createProjectHandle as pr, PresenceSelection as pt, getProjectionState as q, editDocument as qn, OrgVerificationResult as qr, installations as qt, ErrorAuthState as r, ApplicationWorkspace as ri, DocumentDeletedEvent as rn, configureLogging as rr, PreviewValue as rt, getAuthState as s, DeletedResult as si, DocumentPublishedEvent as sn, LogNamespace as sr, reportPresence as st, AuthState as t, ApplicationStudioConfig as ti, ActionErrorEvent as tn, getDatasetsState as tr, PreviewMedia as tt, getIsInDashboardState as u, applications as ui, DocumentUnpublishedEvent as un, createDatasetHandle as ur, DocumentPresenceOptions as ut, SanityProject$1 as v, FetcherDefinition as vi, resolvePermissions as vn, getCommentsState as vr, TransportEvent as vt, stringifyPath$1 as w, Selector as wi, ArchiveReleaseAction as wn, ReplyToCommentOptions as wr, ResolveUsersOptions as wt, joinPaths as x, MutationResult as xi, PermissionDeniedReason as xn, resolveComments as xr, GetUsersOptions as xt, getIndexForKey$1 as y, FetcherSnapshot as yi, subscribeDocumentEvents as yn, parseCommentsOptionsKey as yr, UserPresence as yt, QueryOptions as z, UnpublishDocumentAction as zn, CommentThread as zr, InstallationAccess as zt };
3179
- //# sourceMappingURL=authStore-DKFX8fn7.d.ts.map
3164
+ export { PreviewMedia as $, unpublishDocument as $n, ApplicationInterface as $r, ApplyDocumentActionsOptions as $t, loadMoreUsers as A, DocumentAction as An, updateComment as Ar, organizations as At, parseQueryKey as B, UnscheduleReleaseAction as Bn, ClientStoreState as Br, InstallationInclude as Bt, slicePath$1 as C, Selector as Ci, Action as Cn, ReplyToCommentOptions as Cr, SanityUser as Ct, getCorsErrorProjectId as D, DeleteDocumentAction as Dn, removeComment as Dr, UsersStoreState as Dt, isImportError as E, CreateReleaseAction as En, createComment as Er, UsersGroupState as Et, getActiveReleasesState as F, PublishReleaseAction as Fn, CommentStatus as Fr, organization as Ft, getProjectionState as G, deleteRelease as Gn, observeOrganizationVerificationState as Gr, installations as Gt, ProjectsOptions as H, createDocument as Hn, getClientState as Hr, InstallationsOptions as Ht, getAllReleasesState as I, ReleaseAction as In, CommentTextSelection as Ir, Installation as It, ProjectMember as J, editRelease as Jn, Application as Jr, SetFavoriteInput as Jt, Project as K, discardDocument as Kn, OrgVerificationResult as Kr, FavoriteDocumentContext as Kt, QueryOptions as L, ScheduleReleaseAction as Ln, CommentTextSelectionItem as Lr, InstallationAccess as Lt, resolveUsers as M, EditDocumentOptions as Mn, CommentLocalState as Mr, OrganizationBase as Mt, getPerspectiveState as N, EditReleaseAction as Nn, CommentMessage as Nr, OrganizationMember as Nt, getUserState as O, DeleteReleaseAction as On, replyToComment as Or, Organizations as Ot, ReleaseState as P, PublishDocumentAction as Pn, CommentReaction as Pr, OrganizationOptions as Pt, project as Q, unarchiveRelease as Qn, ApplicationInclude as Qr, ActionsResult as Qt, getQueryKey as R, UnarchiveReleaseAction as Rn, CommentThread as Rr, InstallationActiveConfig as Rt, jsonMatch$1 as S, defineMutation as Si, JsonMatch as Sn, RemoveCommentOptions as Sr, ResolveUsersOptions as St, CORE_SDK_VERSION as T, BoundStoreAction as Ti, CreateDocumentAction as Tn, UpdateCommentOptions as Tr, UserProfile as Tt, projects as U, createRelease as Un, logout as Ur, InstallationsResponse as Ut, resolveQuery as V, archiveRelease as Vn, getClient as Vr, InstallationInterface as Vt, resolveProjection as W, deleteDocument as Wn, handleAuthCallback as Wr, installation as Wt, ProjectMetadata as X, publishRelease as Xn, ApplicationBase as Xr, setFavorite as Xt, ProjectMemberRole as Y, publishDocument as Yn, ApplicationAccess as Yr, favorites as Yt, ProjectOptions as Z, scheduleRelease as Zn, ApplicationDeployment as Zr, getReleaseDocumentId as Zt, SanityDocument$3 as _, FetcherDefinition as _i, resolveDocument as _n, getCommentsState as _r, UserPresence as _t, LoggedOutAuthState as a, DeleteApplicationInput as ai, DocumentEditedEvent as an, LogLevel as ar, reportPresence as at, getPathDepth as b, MutationResult as bi, DocumentPermissionsResult as bn, resolveComments as br, Membership as bt, getCurrentUserState as c, application as ci, DocumentRemotePatchesEvent as cn, LoggerConfig as cr, DocumentPresenceOptions as ct, getLoginUrlState as d, updateApplication as di, TransactionAcceptedEvent as dn, createDocumentTypeHandle as dr, PresenceSelection as dt, ApplicationStudioConfig as ei, applyDocumentActions as en, unscheduleRelease as er, PreviewQueryResult as et, getTokenState as f, AccessResourceType as fi, TransactionRevertedEvent as fn, createProjectHandle as fr, PresenceSelectionPoint as ft, Role as g, Fetcher as gi, getPermissionsState as gn, getCommentsOptionsKey as gr, TransportEvent as gt, ReleaseDocument$1 as h, CacheWriter as hi, getDocumentSyncStatus as hn, getCommentThreadsState as hr, StateEvent as ht, LoggedInAuthState as i, ApplicationsResponse as ii, DocumentDiscardedEvent as in, LogContext as ir, getPresence as it, resolveUser as j, EditDocumentAction as jn, Comment as jr, Organization as jt, getUsersState as k, DiscardDocumentAction as kn, setCommentStatus as kr, OrganizationsOptions as kt, getDashboardOrganizationId as l, applications as li, DocumentTransactionSubmissionResult as ln, createDatasetHandle as lr, PresenceLocation as lt, CurrentUser$1 as m, CacheTag as mi, getDocumentState as mn, ResolveCommentsOptions as mr, RollCallEvent as mt, AuthStoreState as n, ApplicationWorkspace as ni, DocumentCreatedEvent as nn, configureLogging as nr, ProjectionValuePending as nt, LoggingInAuthState as o, DeletedResult as oi, DocumentEvent as on, LogNamespace as or, DisconnectEvent as ot, setAuthToken as p, checkPermissions as pi, DocumentOptions as pn, CommentsOptions as pr, ReportPresenceOptions as pt, ProjectBase as q, editDocument as qn, AuthStateType as qr, FavoriteStatusResponse as qt, ErrorAuthState as r, ApplicationsOptions as ri, DocumentDeletedEvent as rn, InstanceContext as rr, getDocumentPresence as rt, getAuthState as s, UpdateApplicationInput as si, DocumentPublishedEvent as sn, Logger as sr, DocumentPresence as st, AuthState as t, ApplicationVisibility as ti, ActionErrorEvent as tn, datasets as tr, PreviewValue as tt, getIsInDashboardState as u, deleteApplication as ui, DocumentUnpublishedEvent as un, createDocumentHandle as ur, PresencePerspectiveOptions as ut, SanityProject$1 as v, FetcherSnapshot as vi, resolvePermissions as vn, parseCommentsOptionsKey as vr, GetUserOptions as vt, stringifyPath$1 as w, StateSource as wi, ArchiveReleaseAction as wn, SetCommentStatusOptions as wr, SanityUserResponse as wt, joinPaths as x, defineFetcher as xi, PermissionDeniedReason as xn, CreateCommentOptions as xr, ResolveUserOptions as xt, getIndexForKey$1 as y, MutationDefinition as yi, subscribeDocumentEvents as yn, resolveCommentThreads as yr, GetUsersOptions as yt, getQueryState as z, UnpublishDocumentAction as zn, ClientOptions as zr, InstallationBase as zt };
3165
+ //# sourceMappingURL=authStore-C-OEkGaM.d.ts.map