@theaiplatform/miniapp-sdk 0.0.0 → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,8 +8,9 @@ pnpm add @theaiplatform/miniapp-sdk
8
8
  ```
9
9
 
10
10
  The package provides the host-injected SDK API, isolated surface lifecycle
11
- types, browser helpers, manifest schema, and the Rspack/Rslib integration used
12
- to produce descriptor-backed Module Federation targets.
11
+ types, browser helpers, portable React UI components, manifest schema, and the
12
+ Rspack/Rslib integration used to produce descriptor-backed Module Federation
13
+ targets.
13
14
 
14
15
  Start with the [Miniapp SDK documentation](https://docs.theaiplatform.app/miniapps/).
15
16
 
@@ -18,6 +19,10 @@ Start with the [Miniapp SDK documentation](https://docs.theaiplatform.app/miniap
18
19
  - `@theaiplatform/miniapp-sdk`
19
20
  - `@theaiplatform/miniapp-sdk/sdk`
20
21
  - `@theaiplatform/miniapp-sdk/web`
22
+ - `@theaiplatform/miniapp-sdk/ui`
23
+ - `@theaiplatform/miniapp-sdk/ui/styles.css`
24
+ - `@theaiplatform/miniapp-sdk/ui/tailwind.css`
25
+ - `@theaiplatform/miniapp-sdk/ui-components.json`
21
26
  - `@theaiplatform/miniapp-sdk/surface`
22
27
  - `@theaiplatform/miniapp-sdk/config`
23
28
  - `@theaiplatform/miniapp-sdk/rspack`
@@ -25,6 +30,57 @@ Start with the [Miniapp SDK documentation](https://docs.theaiplatform.app/miniap
25
30
 
26
31
  The host API is injected at runtime. Importing an entry point is safe in build
27
32
  tools and tests; host-backed calls fail when used outside a supported runtime.
33
+ `sdk.storage` provides revisioned non-secret JSON scoped by the host to the
34
+ active workspace and exact package. `sdk.presence` provides host-stamped,
35
+ ephemeral room membership and state; package code never supplies participant
36
+ identity.
37
+
38
+ ## Portable UI
39
+
40
+ Import the precompiled stylesheet once at the miniapp entry point, then use
41
+ components from the public UI entry. React 19 is a peer dependency.
42
+
43
+ ```tsx
44
+ import '@theaiplatform/miniapp-sdk/ui/styles.css';
45
+
46
+ import {
47
+ Button,
48
+ Card,
49
+ CardContent,
50
+ CardHeader,
51
+ CardTitle,
52
+ } from '@theaiplatform/miniapp-sdk/ui';
53
+
54
+ export function WelcomeCard() {
55
+ return (
56
+ <Card>
57
+ <CardHeader>
58
+ <CardTitle>Ready to build</CardTitle>
59
+ </CardHeader>
60
+ <CardContent>
61
+ <Button>Continue</Button>
62
+ </CardContent>
63
+ </Card>
64
+ );
65
+ }
66
+ ```
67
+
68
+ Tailwind v4 miniapps can instead import the source integration after
69
+ `tailwindcss` and `tw-animate-css`; it supplies the platform theme and scans the
70
+ SDK's UI bundle for component classes.
71
+
72
+ ```css
73
+ @import 'tailwindcss' source(none);
74
+ @import 'tw-animate-css';
75
+ @import '@theaiplatform/miniapp-sdk/ui/tailwind.css';
76
+
77
+ @source './src';
78
+ ```
79
+
80
+ Use `installMiniAppAppearanceSync()` from the `/web` entry to apply the host's
81
+ light/dark theme and bounded UI scale. Tools and agents can read the exported
82
+ `ui-components.json` catalog to discover the supported component families and
83
+ style entry points without importing application-private packages.
28
84
 
29
85
  ## License and public policies
30
86
 
@@ -2,26 +2,52 @@
2
2
 
3
3
  ## Scope
4
4
 
5
- The `@theaiplatform/miniapp-sdk` package tarball does not embed third-party
6
- package code. Its `./rspack` entry imports separately installed runtime
7
- dependencies. Optional peer dependencies are not distributed with this package
8
- and remain subject to their own licenses.
5
+ The `@theaiplatform/miniapp-sdk` JavaScript entries import separately installed
6
+ runtime dependencies. Its precompiled UI stylesheet is generated with
7
+ Tailwind CSS and `tw-animate-css`; the Tailwind integration stylesheet is
8
+ distributed as source. Optional peer dependencies are not distributed with
9
+ this package and remain subject to their own licenses.
9
10
 
10
11
  The inventory below records the direct and transitive runtime dependency
11
- versions resolved by the release workspace lockfile on July 15, 2026. A
12
+ versions resolved by the release workspace lockfile on July 16, 2026. A
12
13
  downstream application may resolve a different compatible transitive version
13
14
  and is responsible for reviewing the notices required by its own lockfile and
14
15
  distribution artifact.
15
16
 
16
- | Relationship | Package | Version | License |
17
- | ---------------- | ---------------------- | ------: | ------------ |
18
- | Direct | `ajv` | 8.20.0 | MIT |
19
- | Ajv transitive | `fast-deep-equal` | 3.1.3 | MIT |
20
- | Ajv transitive | `fast-uri` | 3.1.2 | BSD-3-Clause |
21
- | Ajv transitive | `json-schema-traverse` | 1.0.0 | MIT |
22
- | Ajv transitive | `require-from-string` | 2.0.2 | MIT |
23
- | Direct | `saxes` | 6.0.0 | ISC |
24
- | Saxes transitive | `xmlchars` | 2.2.0 | MIT |
17
+ | Relationship | Package | Version | License |
18
+ | ---------------- | ------------------------------ | ------: | ------------ |
19
+ | Direct UI | `@radix-ui/react-alert-dialog` | 1.1.15 | MIT |
20
+ | Direct UI | `@radix-ui/react-checkbox` | 1.3.3 | MIT |
21
+ | Direct UI | `@radix-ui/react-compose-refs` | 1.1.2 | MIT |
22
+ | Direct UI | `@radix-ui/react-dialog` | 1.1.15 | MIT |
23
+ | Direct UI | `@radix-ui/react-label` | 2.1.8 | MIT |
24
+ | Direct UI | `@radix-ui/react-progress` | 1.1.8 | MIT |
25
+ | Direct UI | `@radix-ui/react-radio-group` | 1.3.8 | MIT |
26
+ | Direct UI | `@radix-ui/react-scroll-area` | 1.2.10 | MIT |
27
+ | Direct UI | `@radix-ui/react-select` | 2.2.6 | MIT |
28
+ | Direct UI | `@radix-ui/react-separator` | 1.1.8 | MIT |
29
+ | Direct UI | `@radix-ui/react-slider` | 1.3.6 | MIT |
30
+ | Direct UI | `@radix-ui/react-slot` | 1.2.4 | MIT |
31
+ | Direct UI | `@radix-ui/react-tabs` | 1.1.13 | MIT |
32
+ | Direct UI | `@radix-ui/react-toggle` | 1.1.10 | MIT |
33
+ | Direct UI | `@radix-ui/react-toggle-group` | 1.1.11 | MIT |
34
+ | Direct UI | `@radix-ui/react-tooltip` | 1.2.8 | MIT |
35
+ | Direct UI | `class-variance-authority` | 0.7.1 | Apache-2.0 |
36
+ | Direct UI | `clsx` | 2.1.1 | MIT |
37
+ | Direct UI | `lucide-react` | 1.20.0 | ISC |
38
+ | Direct UI | `prism-react-renderer` | 2.4.1 | MIT |
39
+ | Direct UI | `react-resizable-panels` | 4.11.1 | MIT |
40
+ | Direct UI | `tailwind-merge` | 3.6.0 | MIT |
41
+ | Styles build | `@tailwindcss/postcss` | 4.3.0 | MIT |
42
+ | Styles build | `tailwindcss` | 4.3.0 | MIT |
43
+ | Styles build | `tw-animate-css` | 1.4.0 | MIT |
44
+ | Direct | `ajv` | 8.20.0 | MIT |
45
+ | Ajv transitive | `fast-deep-equal` | 3.1.3 | MIT |
46
+ | Ajv transitive | `fast-uri` | 3.1.2 | BSD-3-Clause |
47
+ | Ajv transitive | `json-schema-traverse` | 1.0.0 | MIT |
48
+ | Ajv transitive | `require-from-string` | 2.0.2 | MIT |
49
+ | Direct | `saxes` | 6.0.0 | ISC |
50
+ | Saxes transitive | `xmlchars` | 2.2.0 | MIT |
25
51
 
26
52
  ## License texts
27
53
 
package/dist/index.d.ts CHANGED
@@ -245,6 +245,8 @@ export declare type MiniAppPlatformApi = {
245
245
  open(options: OpenNavigationOptions): void | Promise<void>;
246
246
  };
247
247
  chat: MiniAppChatApi;
248
+ storage: MiniAppStorageApi;
249
+ presence: MiniAppPresenceApi;
248
250
  /** Browser capabilities appear only when the selected target supports them. */
249
251
  auth?: MiniAppAuthApi;
250
252
  vfs?: MiniAppVfsApi;
@@ -253,6 +255,41 @@ export declare type MiniAppPlatformApi = {
253
255
  hasHostHttpRequest?: boolean;
254
256
  };
255
257
 
258
+ export declare type MiniAppPresenceAddress = {
259
+ namespace: string;
260
+ room: string;
261
+ };
262
+
263
+ /**
264
+ * Ephemeral realtime presence scoped by the host to the active workspace and
265
+ * exact package. Participant identity is stamped by the host, not the app.
266
+ */
267
+ export declare type MiniAppPresenceApi = {
268
+ join(options: MiniAppPresenceUpdateOptions): MiniAppMaybePromise<MiniAppPresenceSnapshot>;
269
+ update(options: MiniAppPresenceUpdateOptions): MiniAppMaybePromise<MiniAppPresenceSnapshot>;
270
+ leave(options: MiniAppPresenceAddress): MiniAppMaybePromise<void>;
271
+ subscribe(options: MiniAppPresenceAddress, listener: MiniAppPresenceListener): () => void;
272
+ };
273
+
274
+ export declare type MiniAppPresenceListener = (snapshot: MiniAppPresenceSnapshot) => void;
275
+
276
+ export declare type MiniAppPresenceParticipant = {
277
+ /** Host-derived, ephemeral participant identity. */
278
+ participantId: string;
279
+ displayName: string;
280
+ state: MiniAppJsonValue;
281
+ updatedAtMs: number;
282
+ };
283
+
284
+ export declare type MiniAppPresenceSnapshot = MiniAppPresenceAddress & {
285
+ selfParticipantId: string;
286
+ participants: MiniAppPresenceParticipant[];
287
+ };
288
+
289
+ export declare type MiniAppPresenceUpdateOptions = MiniAppPresenceAddress & {
290
+ state: MiniAppJsonValue;
291
+ };
292
+
256
293
  export declare type MiniAppProject = {
257
294
  id: string;
258
295
  name: string;
@@ -352,6 +389,43 @@ export declare type MiniAppSpecialistTurnResult = {
352
389
  };
353
390
  };
354
391
 
392
+ /** Caller-selected partition inside the host-derived workspace/package scope. */
393
+ export declare type MiniAppStorageAddress = {
394
+ namespace: string;
395
+ key: string;
396
+ };
397
+
398
+ /**
399
+ * Durable, non-secret JSON storage. The host derives workspace and package
400
+ * identity from the authenticated frame; apps control only the namespace and
401
+ * key inside that scope.
402
+ */
403
+ export declare type MiniAppStorageApi = {
404
+ get(options: MiniAppStorageAddress): MiniAppMaybePromise<MiniAppStorageEntry>;
405
+ set(options: MiniAppStorageSetOptions): MiniAppMaybePromise<MiniAppStorageMutationResult>;
406
+ delete(options: MiniAppStorageDeleteOptions): MiniAppMaybePromise<void>;
407
+ };
408
+
409
+ export declare type MiniAppStorageDeleteOptions = MiniAppStorageAddress & {
410
+ expectedRevision: number;
411
+ };
412
+
413
+ export declare type MiniAppStorageEntry = {
414
+ value: MiniAppJsonValue | null;
415
+ /** Null means that no value currently exists at this address. */
416
+ revision: number | null;
417
+ };
418
+
419
+ export declare type MiniAppStorageMutationResult = {
420
+ revision: number;
421
+ };
422
+
423
+ export declare type MiniAppStorageSetOptions = MiniAppStorageAddress & {
424
+ value: MiniAppJsonValue;
425
+ /** Optimistic concurrency token returned by `get`; null creates a missing key. */
426
+ expectedRevision: number | null;
427
+ };
428
+
355
429
  export declare type MiniAppUserProfile = {
356
430
  sub: string;
357
431
  name?: string | null;
@@ -444,8 +444,15 @@ const HOST_ACTION_RESPONSE = 'tap-miniapp-host-action-response';
444
444
  const MAX_PENDING_HOST_ACTIONS = 32;
445
445
  const MAX_CHECKPOINT_REFERENCE_CHARS = 512;
446
446
  const MAX_CHECKPOINT_JSON_BYTES = 32 * 1024;
447
+ const MAX_STORAGE_NAMESPACE_CHARS = 128;
448
+ const MAX_STORAGE_KEY_CHARS = 512;
449
+ const MAX_STORAGE_JSON_BYTES = 5 * 1024 * 1024;
450
+ const MAX_PRESENCE_ROOM_CHARS = 256;
451
+ const MAX_PRESENCE_JSON_BYTES = 16 * 1024;
452
+ const PRESENCE_EVENT = 'tap-miniapp-presence-event';
447
453
  const HOST_ACTION_TIMEOUT_MS = 4000;
448
454
  const pendingHostActions = new Map();
455
+ const presenceListeners = new Map();
449
456
  let hostActionSequence = 0;
450
457
  const validCheckpointReference = (reference) =>
451
458
  typeof reference === 'string' &&
@@ -465,6 +472,24 @@ const checkedCheckpointValue = (value) => {
465
472
  }
466
473
  return value;
467
474
  };
475
+ const validPlatformPartition = (value, maximumLength) =>
476
+ typeof value === 'string' &&
477
+ value.length > 0 &&
478
+ value.trim() === value &&
479
+ Array.from(value).length <= maximumLength &&
480
+ !/[\u0000-\u001f\u007f-\u009f]/u.test(value);
481
+ const checkedPlatformJson = (value, maximumBytes, label) => {
482
+ let encoded;
483
+ try {
484
+ encoded = JSON.stringify(value);
485
+ } catch {
486
+ throw new Error(label + ' must be JSON serializable.');
487
+ }
488
+ if (encoded === undefined || new TextEncoder().encode(encoded).byteLength > maximumBytes) {
489
+ throw new Error(label + ' exceeds the allowed size.');
490
+ }
491
+ return value;
492
+ };
468
493
  const requestHostAction = (action, payload, timeoutMs = HOST_ACTION_TIMEOUT_MS) => {
469
494
  if (pendingHostActions.size >= MAX_PENDING_HOST_ACTIONS) {
470
495
  return Promise.reject(new Error('Too many miniapp host actions are pending.'));
@@ -619,6 +644,79 @@ const invokeSdkHostAction = (action, options, label, timeoutMs = HOST_ACTION_TIM
619
644
  requestHostAction(action, {
620
645
  options: requireOptionsObject(options, label),
621
646
  }, timeoutMs);
647
+ const checkedStorageAddress = (options, label) => {
648
+ requireOptionsObject(options, label);
649
+ if (!validPlatformPartition(options.namespace, MAX_STORAGE_NAMESPACE_CHARS)) {
650
+ throw new Error(label + ' requires a valid namespace.');
651
+ }
652
+ if (!validPlatformPartition(options.key, MAX_STORAGE_KEY_CHARS)) {
653
+ throw new Error(label + ' requires a valid key.');
654
+ }
655
+ return options;
656
+ };
657
+ const storage = Object.freeze({
658
+ get(options) {
659
+ checkedStorageAddress(options, 'app.storage.get');
660
+ return invokeSdkHostAction('tap.platform.storage.get', options, 'app.storage.get');
661
+ },
662
+ set(options) {
663
+ checkedStorageAddress(options, 'app.storage.set');
664
+ if (options.expectedRevision !== null &&
665
+ (!Number.isInteger(options.expectedRevision) || options.expectedRevision < 1)) {
666
+ throw new Error('app.storage.set expectedRevision must be null or a positive integer.');
667
+ }
668
+ checkedPlatformJson(options.value, MAX_STORAGE_JSON_BYTES, 'app.storage.set value');
669
+ return invokeSdkHostAction('tap.platform.storage.set', options, 'app.storage.set', 12000);
670
+ },
671
+ delete(options) {
672
+ checkedStorageAddress(options, 'app.storage.delete');
673
+ if (!Number.isInteger(options.expectedRevision) || options.expectedRevision < 1) {
674
+ throw new Error('app.storage.delete expectedRevision must be a positive integer.');
675
+ }
676
+ return invokeSdkHostAction('tap.platform.storage.delete', options, 'app.storage.delete');
677
+ },
678
+ });
679
+ const checkedPresenceAddress = (options, label) => {
680
+ requireOptionsObject(options, label);
681
+ if (!validPlatformPartition(options.namespace, MAX_STORAGE_NAMESPACE_CHARS)) {
682
+ throw new Error(label + ' requires a valid namespace.');
683
+ }
684
+ if (!validPlatformPartition(options.room, MAX_PRESENCE_ROOM_CHARS)) {
685
+ throw new Error(label + ' requires a valid room.');
686
+ }
687
+ return options;
688
+ };
689
+ const presenceKey = (options) => options.namespace + '\u0000' + options.room;
690
+ const presence = Object.freeze({
691
+ join(options) {
692
+ checkedPresenceAddress(options, 'app.presence.join');
693
+ checkedPlatformJson(options.state, MAX_PRESENCE_JSON_BYTES, 'app.presence.join state');
694
+ return invokeSdkHostAction('tap.platform.presence.join', options, 'app.presence.join');
695
+ },
696
+ update(options) {
697
+ checkedPresenceAddress(options, 'app.presence.update');
698
+ checkedPlatformJson(options.state, MAX_PRESENCE_JSON_BYTES, 'app.presence.update state');
699
+ return invokeSdkHostAction('tap.platform.presence.update', options, 'app.presence.update');
700
+ },
701
+ leave(options) {
702
+ checkedPresenceAddress(options, 'app.presence.leave');
703
+ return invokeSdkHostAction('tap.platform.presence.leave', options, 'app.presence.leave');
704
+ },
705
+ subscribe(options, listener) {
706
+ checkedPresenceAddress(options, 'app.presence.subscribe');
707
+ if (typeof listener !== 'function') {
708
+ throw new Error('app.presence.subscribe requires a listener.');
709
+ }
710
+ const key = presenceKey(options);
711
+ const listeners = presenceListeners.get(key) ?? new Set();
712
+ listeners.add(listener);
713
+ presenceListeners.set(key, listeners);
714
+ return () => {
715
+ listeners.delete(listener);
716
+ if (listeners.size === 0) presenceListeners.delete(key);
717
+ };
718
+ },
719
+ });
622
720
  const channels = Object.freeze({
623
721
  create(options) {
624
722
  requireOptionString(options?.name, 'app.channels.create name');
@@ -893,6 +991,8 @@ const miniappSdk = Object.freeze({
893
991
  workflows,
894
992
  navigation,
895
993
  chat: miniappChat,
994
+ storage,
995
+ presence,
896
996
  auth: platformAuth,
897
997
  vfs: platformVfs,
898
998
  specialist: platformSpecialist,
@@ -1021,6 +1121,24 @@ const onHostMessage = async (event) => {
1021
1121
  }
1022
1122
  return;
1023
1123
  }
1124
+ if (
1125
+ message.type === PRESENCE_EVENT &&
1126
+ validPlatformPartition(message.namespace, MAX_STORAGE_NAMESPACE_CHARS) &&
1127
+ validPlatformPartition(message.room, MAX_PRESENCE_ROOM_CHARS) &&
1128
+ typeof message.selfParticipantId === 'string' &&
1129
+ Array.isArray(message.participants)
1130
+ ) {
1131
+ const snapshot = Object.freeze({
1132
+ namespace: message.namespace,
1133
+ room: message.room,
1134
+ selfParticipantId: message.selfParticipantId,
1135
+ participants: message.participants,
1136
+ });
1137
+ for (const listener of presenceListeners.get(presenceKey(snapshot)) ?? []) {
1138
+ try { await listener(snapshot); } catch { /* isolate observer failures */ }
1139
+ }
1140
+ return;
1141
+ }
1024
1142
  if (message.type === HOST_ACTION_RESPONSE) {
1025
1143
  const requestId = typeof message.id === 'string' ? message.id : '';
1026
1144
  const pending = pendingHostActions.get(requestId);
@@ -1141,6 +1259,7 @@ window.addEventListener('pagehide', () => {
1141
1259
  window.removeEventListener('message', onHostMessage);
1142
1260
  eventListeners.clear();
1143
1261
  hostAuthorityListeners.clear();
1262
+ presenceListeners.clear();
1144
1263
  for (const pending of pendingHostActions.values()) {
1145
1264
  clearTimeout(pending.timeout);
1146
1265
  pending.reject(new Error('The mini app document was removed.'));
package/dist/sdk.d.ts CHANGED
@@ -234,6 +234,8 @@ export declare type MiniAppPlatformApi = {
234
234
  open(options: OpenNavigationOptions): void | Promise<void>;
235
235
  };
236
236
  chat: MiniAppChatApi;
237
+ storage: MiniAppStorageApi;
238
+ presence: MiniAppPresenceApi;
237
239
  /** Browser capabilities appear only when the selected target supports them. */
238
240
  auth?: MiniAppAuthApi;
239
241
  vfs?: MiniAppVfsApi;
@@ -242,6 +244,41 @@ export declare type MiniAppPlatformApi = {
242
244
  hasHostHttpRequest?: boolean;
243
245
  };
244
246
 
247
+ export declare type MiniAppPresenceAddress = {
248
+ namespace: string;
249
+ room: string;
250
+ };
251
+
252
+ /**
253
+ * Ephemeral realtime presence scoped by the host to the active workspace and
254
+ * exact package. Participant identity is stamped by the host, not the app.
255
+ */
256
+ export declare type MiniAppPresenceApi = {
257
+ join(options: MiniAppPresenceUpdateOptions): MiniAppMaybePromise<MiniAppPresenceSnapshot>;
258
+ update(options: MiniAppPresenceUpdateOptions): MiniAppMaybePromise<MiniAppPresenceSnapshot>;
259
+ leave(options: MiniAppPresenceAddress): MiniAppMaybePromise<void>;
260
+ subscribe(options: MiniAppPresenceAddress, listener: MiniAppPresenceListener): () => void;
261
+ };
262
+
263
+ export declare type MiniAppPresenceListener = (snapshot: MiniAppPresenceSnapshot) => void;
264
+
265
+ export declare type MiniAppPresenceParticipant = {
266
+ /** Host-derived, ephemeral participant identity. */
267
+ participantId: string;
268
+ displayName: string;
269
+ state: MiniAppJsonValue;
270
+ updatedAtMs: number;
271
+ };
272
+
273
+ export declare type MiniAppPresenceSnapshot = MiniAppPresenceAddress & {
274
+ selfParticipantId: string;
275
+ participants: MiniAppPresenceParticipant[];
276
+ };
277
+
278
+ export declare type MiniAppPresenceUpdateOptions = MiniAppPresenceAddress & {
279
+ state: MiniAppJsonValue;
280
+ };
281
+
245
282
  export declare type MiniAppProject = {
246
283
  id: string;
247
284
  name: string;
@@ -341,6 +378,43 @@ export declare type MiniAppSpecialistTurnResult = {
341
378
  };
342
379
  };
343
380
 
381
+ /** Caller-selected partition inside the host-derived workspace/package scope. */
382
+ export declare type MiniAppStorageAddress = {
383
+ namespace: string;
384
+ key: string;
385
+ };
386
+
387
+ /**
388
+ * Durable, non-secret JSON storage. The host derives workspace and package
389
+ * identity from the authenticated frame; apps control only the namespace and
390
+ * key inside that scope.
391
+ */
392
+ export declare type MiniAppStorageApi = {
393
+ get(options: MiniAppStorageAddress): MiniAppMaybePromise<MiniAppStorageEntry>;
394
+ set(options: MiniAppStorageSetOptions): MiniAppMaybePromise<MiniAppStorageMutationResult>;
395
+ delete(options: MiniAppStorageDeleteOptions): MiniAppMaybePromise<void>;
396
+ };
397
+
398
+ export declare type MiniAppStorageDeleteOptions = MiniAppStorageAddress & {
399
+ expectedRevision: number;
400
+ };
401
+
402
+ export declare type MiniAppStorageEntry = {
403
+ value: MiniAppJsonValue | null;
404
+ /** Null means that no value currently exists at this address. */
405
+ revision: number | null;
406
+ };
407
+
408
+ export declare type MiniAppStorageMutationResult = {
409
+ revision: number;
410
+ };
411
+
412
+ export declare type MiniAppStorageSetOptions = MiniAppStorageAddress & {
413
+ value: MiniAppJsonValue;
414
+ /** Optimistic concurrency token returned by `get`; null creates a missing key. */
415
+ expectedRevision: number | null;
416
+ };
417
+
344
418
  export declare type MiniAppUserProfile = {
345
419
  sub: string;
346
420
  name?: string | null;