@01.software/sdk 0.2.9-dev.260314.f493447 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/dist/auth.d.cts +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/const-BpirbGBD.d.cts +19 -0
- package/dist/const-qZSQiSSC.d.ts +19 -0
- package/dist/index.cjs +229 -79
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +114 -196
- package/dist/index.d.ts +114 -196
- package/dist/index.js +229 -79
- package/dist/index.js.map +1 -1
- package/dist/{payload-types-ggU6BNuH.d.cts → payload-types-CZiaL4Wr.d.cts} +6 -5
- package/dist/{payload-types-ggU6BNuH.d.ts → payload-types-CZiaL4Wr.d.ts} +6 -5
- package/dist/realtime-DupPIYx-.d.cts +33 -0
- package/dist/realtime-DupPIYx-.d.ts +33 -0
- package/dist/realtime.cjs +261 -0
- package/dist/realtime.cjs.map +1 -0
- package/dist/realtime.d.cts +38 -0
- package/dist/realtime.d.ts +38 -0
- package/dist/realtime.js +239 -0
- package/dist/realtime.js.map +1 -0
- package/dist/ui/code-block.cjs +3 -1
- package/dist/ui/code-block.cjs.map +1 -1
- package/dist/ui/code-block.js +4 -2
- package/dist/ui/code-block.js.map +1 -1
- package/dist/ui/flow.cjs +18 -3
- package/dist/ui/flow.cjs.map +1 -1
- package/dist/ui/flow.js +18 -3
- package/dist/ui/flow.js.map +1 -1
- package/dist/ui/form.d.cts +1 -1
- package/dist/ui/form.d.ts +1 -1
- package/dist/ui/video.cjs +219 -0
- package/dist/ui/video.cjs.map +1 -0
- package/dist/ui/video.d.cts +96 -0
- package/dist/ui/video.d.ts +96 -0
- package/dist/ui/video.js +191 -0
- package/dist/ui/video.js.map +1 -0
- package/dist/video-DbLL8yuc.d.cts +85 -0
- package/dist/video-DbLL8yuc.d.ts +85 -0
- package/dist/webhook-3iL9OEyq.d.cts +20 -0
- package/dist/webhook-DuTqrH9x.d.ts +20 -0
- package/dist/webhook.cjs +8 -8
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.d.cts +3 -2
- package/dist/webhook.d.ts +3 -2
- package/dist/webhook.js +8 -8
- package/dist/webhook.js.map +1 -1
- package/package.json +29 -4
- package/dist/webhook-B54a-HGd.d.ts +0 -35
- package/dist/webhook-DInps2xX.d.cts +0 -35
|
@@ -305,9 +305,6 @@ interface User {
|
|
|
305
305
|
emailPreferences?: {
|
|
306
306
|
usageAlerts?: boolean | null;
|
|
307
307
|
};
|
|
308
|
-
fieldConfigs?: {
|
|
309
|
-
[k: string]: unknown;
|
|
310
|
-
} | unknown[] | string | number | boolean | null;
|
|
311
308
|
updatedAt: string;
|
|
312
309
|
createdAt: string;
|
|
313
310
|
email: string;
|
|
@@ -340,6 +337,10 @@ interface Tenant {
|
|
|
340
337
|
owner: string | User;
|
|
341
338
|
plan: 'free' | 'starter' | 'basic' | 'pro' | 'enterprise';
|
|
342
339
|
features?: ('ecommerce' | 'playlists' | 'galleries' | 'forms' | 'posts' | 'documents' | 'flows' | 'videos' | 'live-streaming')[] | null;
|
|
340
|
+
/**
|
|
341
|
+
* Require email verification on customer registration. Verification token is delivered via webhook (operation: verification). You must configure a webhook URL first.
|
|
342
|
+
*/
|
|
343
|
+
requireEmailVerification?: boolean | null;
|
|
343
344
|
/**
|
|
344
345
|
* Allowed CORS origins for browser SDK requests. Empty = all origins allowed.
|
|
345
346
|
*/
|
|
@@ -3450,7 +3451,6 @@ interface UsersSelect<T extends boolean = true> {
|
|
|
3450
3451
|
emailPreferences?: T | {
|
|
3451
3452
|
usageAlerts?: T;
|
|
3452
3453
|
};
|
|
3453
|
-
fieldConfigs?: T;
|
|
3454
3454
|
updatedAt?: T;
|
|
3455
3455
|
createdAt?: T;
|
|
3456
3456
|
email?: T;
|
|
@@ -3613,6 +3613,7 @@ interface TenantsSelect<T extends boolean = true> {
|
|
|
3613
3613
|
owner?: T;
|
|
3614
3614
|
plan?: T;
|
|
3615
3615
|
features?: T;
|
|
3616
|
+
requireEmailVerification?: T;
|
|
3616
3617
|
cors?: T | {
|
|
3617
3618
|
origin?: T;
|
|
3618
3619
|
id?: T;
|
|
@@ -5309,4 +5310,4 @@ declare module 'payload' {
|
|
|
5309
5310
|
}
|
|
5310
5311
|
}
|
|
5311
5312
|
|
|
5312
|
-
export type { Document as $, Audience as A, BrandLogo as B,
|
|
5313
|
+
export type { Document as $, Audience as A, BrandLogo as B, Config as C, ProductCollection as D, Exchange as E, Form as F, Customer as G, CustomerGroup as H, IframeBlock as I, CustomerAddress as J, FulfillmentItem as K, LiveStream as L, ReturnProduct as M, ExchangeProduct as N, Order as O, Product as P, OrderStatusLog as Q, Return as R, SupportedTimezones as S, Transaction as T, UserAuthOperations as U, Video as V, Discount as W, Post as X, PostAuthor as Y, PostCategory as Z, PostTag as _, OrderProduct as a, DocumentTypesSelect as a$, DocumentType as a0, DocumentCategory as a1, Playlist as a2, PlaylistCategory as a3, PlaylistTag as a4, Music as a5, Gallery as a6, GalleryCategory as a7, GalleryTag as a8, GalleryItem as a9, ProductTagsSelect as aA, ProductCollectionsSelect as aB, BrandsSelect as aC, BrandLogosSelect as aD, OrdersSelect as aE, OrderProductsSelect as aF, TransactionsSelect as aG, OrderStatusLogsSelect as aH, FulfillmentsSelect as aI, FulfillmentItemsSelect as aJ, ReturnsSelect as aK, ReturnProductsSelect as aL, ExchangesSelect as aM, ExchangeProductsSelect as aN, ShippingPoliciesSelect as aO, CustomersSelect as aP, CustomerAddressesSelect as aQ, CustomerGroupsSelect as aR, CartsSelect as aS, CartItemsSelect as aT, DiscountsSelect as aU, PostsSelect as aV, PostAuthorsSelect as aW, PostCategoriesSelect as aX, PostTagsSelect as aY, DocumentsSelect as aZ, DocumentCategoriesSelect as a_, Flow as aa, FlowCategory as ab, FlowTag as ac, FlowNodeType as ad, FlowEdgeType as ae, FormSubmission as af, PayloadKv as ag, PayloadLockedDocument as ah, PayloadPreference as ai, PayloadMigration as aj, UsersSelect as ak, FieldConfigsSelect as al, ImagesSelect as am, SystemMediaSelect as an, AudiencesSelect as ao, EmailLogsSelect as ap, TenantsSelect as aq, TenantMetadataSelect as ar, ApiUsageSelect as as, SubscriptionsSelect as at, BillingHistorySelect as au, TenantLogosSelect as av, ProductsSelect as aw, ProductVariantsSelect as ax, ProductOptionsSelect as ay, ProductCategoriesSelect as az, Fulfillment as b, PlaylistsSelect as b0, PlaylistCategoriesSelect as b1, PlaylistTagsSelect as b2, MusicsSelect as b3, GalleriesSelect as b4, GalleryCategoriesSelect as b5, GalleryTagsSelect as b6, GalleryItemsSelect as b7, FlowsSelect as b8, FlowNodeTypesSelect as b9, FlowEdgeTypesSelect as ba, FlowCategoriesSelect as bb, FlowTagsSelect as bc, VideosSelect as bd, VideoCategoriesSelect as be, VideoTagsSelect as bf, LiveStreamsSelect as bg, FormsSelect as bh, FormSubmissionsSelect as bi, PayloadKvSelect as bj, PayloadLockedDocumentsSelect as bk, PayloadPreferencesSelect as bl, PayloadMigrationsSelect as bm, CollectionsWidget as bn, Auth as bo, Cart as c, CartItem as d, CustomerAuthOperations as e, PlayerBlock as f, CodeBlock as g, User as h, Tenant as i, FieldConfig as j, Image as k, SystemMedia as l, EmailLog as m, TenantMetadatum as n, ApiUsage as o, Subscription as p, BillingHistory as q, TenantLogo as r, VideoCategory as s, VideoTag as t, ProductVariant as u, ProductOption as v, ProductCategory as w, ProductTag as x, Brand as y, ShippingPolicy as z };
|
|
@@ -305,9 +305,6 @@ interface User {
|
|
|
305
305
|
emailPreferences?: {
|
|
306
306
|
usageAlerts?: boolean | null;
|
|
307
307
|
};
|
|
308
|
-
fieldConfigs?: {
|
|
309
|
-
[k: string]: unknown;
|
|
310
|
-
} | unknown[] | string | number | boolean | null;
|
|
311
308
|
updatedAt: string;
|
|
312
309
|
createdAt: string;
|
|
313
310
|
email: string;
|
|
@@ -340,6 +337,10 @@ interface Tenant {
|
|
|
340
337
|
owner: string | User;
|
|
341
338
|
plan: 'free' | 'starter' | 'basic' | 'pro' | 'enterprise';
|
|
342
339
|
features?: ('ecommerce' | 'playlists' | 'galleries' | 'forms' | 'posts' | 'documents' | 'flows' | 'videos' | 'live-streaming')[] | null;
|
|
340
|
+
/**
|
|
341
|
+
* Require email verification on customer registration. Verification token is delivered via webhook (operation: verification). You must configure a webhook URL first.
|
|
342
|
+
*/
|
|
343
|
+
requireEmailVerification?: boolean | null;
|
|
343
344
|
/**
|
|
344
345
|
* Allowed CORS origins for browser SDK requests. Empty = all origins allowed.
|
|
345
346
|
*/
|
|
@@ -3450,7 +3451,6 @@ interface UsersSelect<T extends boolean = true> {
|
|
|
3450
3451
|
emailPreferences?: T | {
|
|
3451
3452
|
usageAlerts?: T;
|
|
3452
3453
|
};
|
|
3453
|
-
fieldConfigs?: T;
|
|
3454
3454
|
updatedAt?: T;
|
|
3455
3455
|
createdAt?: T;
|
|
3456
3456
|
email?: T;
|
|
@@ -3613,6 +3613,7 @@ interface TenantsSelect<T extends boolean = true> {
|
|
|
3613
3613
|
owner?: T;
|
|
3614
3614
|
plan?: T;
|
|
3615
3615
|
features?: T;
|
|
3616
|
+
requireEmailVerification?: T;
|
|
3616
3617
|
cors?: T | {
|
|
3617
3618
|
origin?: T;
|
|
3618
3619
|
id?: T;
|
|
@@ -5309,4 +5310,4 @@ declare module 'payload' {
|
|
|
5309
5310
|
}
|
|
5310
5311
|
}
|
|
5311
5312
|
|
|
5312
|
-
export type { Document as $, Audience as A, BrandLogo as B,
|
|
5313
|
+
export type { Document as $, Audience as A, BrandLogo as B, Config as C, ProductCollection as D, Exchange as E, Form as F, Customer as G, CustomerGroup as H, IframeBlock as I, CustomerAddress as J, FulfillmentItem as K, LiveStream as L, ReturnProduct as M, ExchangeProduct as N, Order as O, Product as P, OrderStatusLog as Q, Return as R, SupportedTimezones as S, Transaction as T, UserAuthOperations as U, Video as V, Discount as W, Post as X, PostAuthor as Y, PostCategory as Z, PostTag as _, OrderProduct as a, DocumentTypesSelect as a$, DocumentType as a0, DocumentCategory as a1, Playlist as a2, PlaylistCategory as a3, PlaylistTag as a4, Music as a5, Gallery as a6, GalleryCategory as a7, GalleryTag as a8, GalleryItem as a9, ProductTagsSelect as aA, ProductCollectionsSelect as aB, BrandsSelect as aC, BrandLogosSelect as aD, OrdersSelect as aE, OrderProductsSelect as aF, TransactionsSelect as aG, OrderStatusLogsSelect as aH, FulfillmentsSelect as aI, FulfillmentItemsSelect as aJ, ReturnsSelect as aK, ReturnProductsSelect as aL, ExchangesSelect as aM, ExchangeProductsSelect as aN, ShippingPoliciesSelect as aO, CustomersSelect as aP, CustomerAddressesSelect as aQ, CustomerGroupsSelect as aR, CartsSelect as aS, CartItemsSelect as aT, DiscountsSelect as aU, PostsSelect as aV, PostAuthorsSelect as aW, PostCategoriesSelect as aX, PostTagsSelect as aY, DocumentsSelect as aZ, DocumentCategoriesSelect as a_, Flow as aa, FlowCategory as ab, FlowTag as ac, FlowNodeType as ad, FlowEdgeType as ae, FormSubmission as af, PayloadKv as ag, PayloadLockedDocument as ah, PayloadPreference as ai, PayloadMigration as aj, UsersSelect as ak, FieldConfigsSelect as al, ImagesSelect as am, SystemMediaSelect as an, AudiencesSelect as ao, EmailLogsSelect as ap, TenantsSelect as aq, TenantMetadataSelect as ar, ApiUsageSelect as as, SubscriptionsSelect as at, BillingHistorySelect as au, TenantLogosSelect as av, ProductsSelect as aw, ProductVariantsSelect as ax, ProductOptionsSelect as ay, ProductCategoriesSelect as az, Fulfillment as b, PlaylistsSelect as b0, PlaylistCategoriesSelect as b1, PlaylistTagsSelect as b2, MusicsSelect as b3, GalleriesSelect as b4, GalleryCategoriesSelect as b5, GalleryTagsSelect as b6, GalleryItemsSelect as b7, FlowsSelect as b8, FlowNodeTypesSelect as b9, FlowEdgeTypesSelect as ba, FlowCategoriesSelect as bb, FlowTagsSelect as bc, VideosSelect as bd, VideoCategoriesSelect as be, VideoTagsSelect as bf, LiveStreamsSelect as bg, FormsSelect as bh, FormSubmissionsSelect as bi, PayloadKvSelect as bj, PayloadLockedDocumentsSelect as bk, PayloadPreferencesSelect as bl, PayloadMigrationsSelect as bm, CollectionsWidget as bn, Auth as bo, Cart as c, CartItem as d, CustomerAuthOperations as e, PlayerBlock as f, CodeBlock as g, User as h, Tenant as i, FieldConfig as j, Image as k, SystemMedia as l, EmailLog as m, TenantMetadatum as n, ApiUsage as o, Subscription as p, BillingHistory as q, TenantLogo as r, VideoCategory as s, VideoTag as t, ProductVariant as u, ProductOption as v, ProductCategory as w, ProductTag as x, Brand as y, ShippingPolicy as z };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch-based SSE connection manager for real-time collection change events.
|
|
3
|
+
* Uses fetch + ReadableStream to support custom auth headers (unlike native EventSource).
|
|
4
|
+
*/
|
|
5
|
+
interface RealtimeEvent {
|
|
6
|
+
collection: string;
|
|
7
|
+
operation: string;
|
|
8
|
+
id: string | null;
|
|
9
|
+
timestamp: string;
|
|
10
|
+
}
|
|
11
|
+
type RealtimeListener = (event: RealtimeEvent) => void;
|
|
12
|
+
declare class RealtimeConnection {
|
|
13
|
+
private baseUrl;
|
|
14
|
+
private clientKey;
|
|
15
|
+
private getToken;
|
|
16
|
+
private collections?;
|
|
17
|
+
private abortController;
|
|
18
|
+
private reconnectAttempt;
|
|
19
|
+
private noTokenAttempts;
|
|
20
|
+
private reconnectTimer;
|
|
21
|
+
private listeners;
|
|
22
|
+
private _connected;
|
|
23
|
+
constructor(baseUrl: string, clientKey: string, getToken: () => string | null, collections?: string[] | undefined);
|
|
24
|
+
get connected(): boolean;
|
|
25
|
+
addListener(fn: RealtimeListener): () => void;
|
|
26
|
+
connect(): void;
|
|
27
|
+
disconnect(): void;
|
|
28
|
+
private startStream;
|
|
29
|
+
private readStream;
|
|
30
|
+
private scheduleReconnect;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { type RealtimeEvent as R, RealtimeConnection as a, type RealtimeListener as b };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetch-based SSE connection manager for real-time collection change events.
|
|
3
|
+
* Uses fetch + ReadableStream to support custom auth headers (unlike native EventSource).
|
|
4
|
+
*/
|
|
5
|
+
interface RealtimeEvent {
|
|
6
|
+
collection: string;
|
|
7
|
+
operation: string;
|
|
8
|
+
id: string | null;
|
|
9
|
+
timestamp: string;
|
|
10
|
+
}
|
|
11
|
+
type RealtimeListener = (event: RealtimeEvent) => void;
|
|
12
|
+
declare class RealtimeConnection {
|
|
13
|
+
private baseUrl;
|
|
14
|
+
private clientKey;
|
|
15
|
+
private getToken;
|
|
16
|
+
private collections?;
|
|
17
|
+
private abortController;
|
|
18
|
+
private reconnectAttempt;
|
|
19
|
+
private noTokenAttempts;
|
|
20
|
+
private reconnectTimer;
|
|
21
|
+
private listeners;
|
|
22
|
+
private _connected;
|
|
23
|
+
constructor(baseUrl: string, clientKey: string, getToken: () => string | null, collections?: string[] | undefined);
|
|
24
|
+
get connected(): boolean;
|
|
25
|
+
addListener(fn: RealtimeListener): () => void;
|
|
26
|
+
connect(): void;
|
|
27
|
+
disconnect(): void;
|
|
28
|
+
private startStream;
|
|
29
|
+
private readStream;
|
|
30
|
+
private scheduleReconnect;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export { type RealtimeEvent as R, RealtimeConnection as a, type RealtimeListener as b };
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var __async = (__this, __arguments, generator) => {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
var fulfilled = (value) => {
|
|
22
|
+
try {
|
|
23
|
+
step(generator.next(value));
|
|
24
|
+
} catch (e) {
|
|
25
|
+
reject(e);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
var rejected = (value) => {
|
|
29
|
+
try {
|
|
30
|
+
step(generator.throw(value));
|
|
31
|
+
} catch (e) {
|
|
32
|
+
reject(e);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
36
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// src/realtime.ts
|
|
41
|
+
var realtime_exports = {};
|
|
42
|
+
__export(realtime_exports, {
|
|
43
|
+
RealtimeConnection: () => RealtimeConnection,
|
|
44
|
+
useRealtimeQuery: () => useRealtimeQuery
|
|
45
|
+
});
|
|
46
|
+
module.exports = __toCommonJS(realtime_exports);
|
|
47
|
+
|
|
48
|
+
// src/core/query/realtime-hooks.ts
|
|
49
|
+
var import_react = require("react");
|
|
50
|
+
var import_react_query = require("@tanstack/react-query");
|
|
51
|
+
|
|
52
|
+
// src/core/query/realtime.ts
|
|
53
|
+
var INITIAL_RECONNECT_DELAY = 1e3;
|
|
54
|
+
var MAX_RECONNECT_DELAY = 3e4;
|
|
55
|
+
var RECONNECT_BACKOFF_FACTOR = 2;
|
|
56
|
+
var MAX_NO_TOKEN_RETRIES = 5;
|
|
57
|
+
var RealtimeConnection = class {
|
|
58
|
+
constructor(baseUrl, clientKey, getToken, collections) {
|
|
59
|
+
this.baseUrl = baseUrl;
|
|
60
|
+
this.clientKey = clientKey;
|
|
61
|
+
this.getToken = getToken;
|
|
62
|
+
this.collections = collections;
|
|
63
|
+
this.abortController = null;
|
|
64
|
+
this.reconnectAttempt = 0;
|
|
65
|
+
this.noTokenAttempts = 0;
|
|
66
|
+
this.reconnectTimer = null;
|
|
67
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
68
|
+
this._connected = false;
|
|
69
|
+
}
|
|
70
|
+
get connected() {
|
|
71
|
+
return this._connected;
|
|
72
|
+
}
|
|
73
|
+
addListener(fn) {
|
|
74
|
+
this.listeners.add(fn);
|
|
75
|
+
return () => this.listeners.delete(fn);
|
|
76
|
+
}
|
|
77
|
+
connect() {
|
|
78
|
+
if (this.abortController) return;
|
|
79
|
+
this.abortController = new AbortController();
|
|
80
|
+
this.startStream(this.abortController.signal);
|
|
81
|
+
}
|
|
82
|
+
disconnect() {
|
|
83
|
+
this._connected = false;
|
|
84
|
+
if (this.reconnectTimer) {
|
|
85
|
+
clearTimeout(this.reconnectTimer);
|
|
86
|
+
this.reconnectTimer = null;
|
|
87
|
+
}
|
|
88
|
+
if (this.abortController) {
|
|
89
|
+
this.abortController.abort();
|
|
90
|
+
this.abortController = null;
|
|
91
|
+
}
|
|
92
|
+
this.reconnectAttempt = 0;
|
|
93
|
+
this.noTokenAttempts = 0;
|
|
94
|
+
}
|
|
95
|
+
startStream(signal) {
|
|
96
|
+
return __async(this, null, function* () {
|
|
97
|
+
var _a;
|
|
98
|
+
const token = this.getToken();
|
|
99
|
+
if (!token) {
|
|
100
|
+
this.noTokenAttempts++;
|
|
101
|
+
if (this.noTokenAttempts >= MAX_NO_TOKEN_RETRIES) {
|
|
102
|
+
this._connected = false;
|
|
103
|
+
this.abortController = null;
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
this.scheduleReconnect();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
this.noTokenAttempts = 0;
|
|
110
|
+
const params = ((_a = this.collections) == null ? void 0 : _a.length) ? `?collections=${this.collections.join(",")}` : "";
|
|
111
|
+
const url = `${this.baseUrl}/api/events/stream${params}`;
|
|
112
|
+
try {
|
|
113
|
+
const response = yield fetch(url, {
|
|
114
|
+
headers: {
|
|
115
|
+
"X-Client-Key": this.clientKey,
|
|
116
|
+
Authorization: `Bearer ${token}`
|
|
117
|
+
},
|
|
118
|
+
signal
|
|
119
|
+
});
|
|
120
|
+
if (!response.ok) {
|
|
121
|
+
if (response.status === 401) {
|
|
122
|
+
this.scheduleReconnect();
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
throw new Error(`SSE connection failed: ${response.status}`);
|
|
126
|
+
}
|
|
127
|
+
if (!response.body) {
|
|
128
|
+
throw new Error("SSE response has no body");
|
|
129
|
+
}
|
|
130
|
+
this._connected = true;
|
|
131
|
+
this.reconnectAttempt = 0;
|
|
132
|
+
yield this.readStream(response.body, signal);
|
|
133
|
+
} catch (e) {
|
|
134
|
+
if (signal.aborted) return;
|
|
135
|
+
this._connected = false;
|
|
136
|
+
this.scheduleReconnect();
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
readStream(body, signal) {
|
|
141
|
+
return __async(this, null, function* () {
|
|
142
|
+
var _a;
|
|
143
|
+
const reader = body.getReader();
|
|
144
|
+
const decoder = new TextDecoder();
|
|
145
|
+
let buffer = "";
|
|
146
|
+
let currentEvent = "";
|
|
147
|
+
let currentData = "";
|
|
148
|
+
try {
|
|
149
|
+
while (true) {
|
|
150
|
+
const { done, value } = yield reader.read();
|
|
151
|
+
if (done || signal.aborted) break;
|
|
152
|
+
buffer += decoder.decode(value, { stream: true });
|
|
153
|
+
const lines = buffer.split("\n");
|
|
154
|
+
buffer = (_a = lines.pop()) != null ? _a : "";
|
|
155
|
+
for (const line of lines) {
|
|
156
|
+
if (line.startsWith("event: ")) {
|
|
157
|
+
currentEvent = line.slice(7);
|
|
158
|
+
} else if (line.startsWith("data: ")) {
|
|
159
|
+
currentData += (currentData ? "\n" : "") + line.slice(6);
|
|
160
|
+
} else if (line === "") {
|
|
161
|
+
if (currentEvent === "collection:change" && currentData) {
|
|
162
|
+
try {
|
|
163
|
+
const event = JSON.parse(currentData);
|
|
164
|
+
for (const listener of this.listeners) {
|
|
165
|
+
try {
|
|
166
|
+
listener(event);
|
|
167
|
+
} catch (e) {
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
} catch (e) {
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
currentEvent = "";
|
|
174
|
+
currentData = "";
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
} catch (e) {
|
|
179
|
+
} finally {
|
|
180
|
+
reader.releaseLock();
|
|
181
|
+
this._connected = false;
|
|
182
|
+
if (!signal.aborted) {
|
|
183
|
+
this.scheduleReconnect();
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
scheduleReconnect() {
|
|
189
|
+
if (this.reconnectTimer) return;
|
|
190
|
+
const delay = Math.min(
|
|
191
|
+
INITIAL_RECONNECT_DELAY * Math.pow(RECONNECT_BACKOFF_FACTOR, this.reconnectAttempt),
|
|
192
|
+
MAX_RECONNECT_DELAY
|
|
193
|
+
);
|
|
194
|
+
this.reconnectAttempt++;
|
|
195
|
+
this.reconnectTimer = setTimeout(() => {
|
|
196
|
+
this.reconnectTimer = null;
|
|
197
|
+
this.abortController = new AbortController();
|
|
198
|
+
this.startStream(this.abortController.signal);
|
|
199
|
+
}, delay);
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
// src/core/client/types.ts
|
|
204
|
+
function resolveApiUrl() {
|
|
205
|
+
const envUrl = process.env.SOFTWARE_API_URL || process.env.NEXT_PUBLIC_SOFTWARE_API_URL;
|
|
206
|
+
if (envUrl) {
|
|
207
|
+
return envUrl.replace(/\/$/, "");
|
|
208
|
+
}
|
|
209
|
+
return "https://api.01.software";
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// src/core/query/query-keys.ts
|
|
213
|
+
function collectionKeys(collection) {
|
|
214
|
+
return {
|
|
215
|
+
all: [collection],
|
|
216
|
+
lists: () => [collection, "list"],
|
|
217
|
+
list: (options) => [collection, "list", options],
|
|
218
|
+
details: () => [collection, "detail"],
|
|
219
|
+
detail: (id, options) => [collection, "detail", id, options],
|
|
220
|
+
infinites: () => [collection, "infinite"],
|
|
221
|
+
infinite: (options) => [collection, "infinite", options]
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// src/core/query/realtime-hooks.ts
|
|
226
|
+
function useRealtimeQuery(options) {
|
|
227
|
+
const { clientKey, getToken, collections, enabled = true } = options;
|
|
228
|
+
const queryClient = (0, import_react_query.useQueryClient)();
|
|
229
|
+
const [connected, setConnected] = (0, import_react.useState)(false);
|
|
230
|
+
const [lastEvent, setLastEvent] = (0, import_react.useState)(null);
|
|
231
|
+
const connectionRef = (0, import_react.useRef)(null);
|
|
232
|
+
(0, import_react.useEffect)(() => {
|
|
233
|
+
if (!enabled || !clientKey) return;
|
|
234
|
+
const baseUrl = resolveApiUrl();
|
|
235
|
+
const conn = new RealtimeConnection(
|
|
236
|
+
baseUrl,
|
|
237
|
+
clientKey,
|
|
238
|
+
getToken,
|
|
239
|
+
collections
|
|
240
|
+
);
|
|
241
|
+
connectionRef.current = conn;
|
|
242
|
+
const removeListener = conn.addListener((event) => {
|
|
243
|
+
setLastEvent(event);
|
|
244
|
+
const keys = collectionKeys(event.collection);
|
|
245
|
+
queryClient.invalidateQueries({ queryKey: keys.all });
|
|
246
|
+
});
|
|
247
|
+
const pollInterval = setInterval(() => {
|
|
248
|
+
setConnected(conn.connected);
|
|
249
|
+
}, 1e3);
|
|
250
|
+
conn.connect();
|
|
251
|
+
return () => {
|
|
252
|
+
conn.disconnect();
|
|
253
|
+
removeListener();
|
|
254
|
+
clearInterval(pollInterval);
|
|
255
|
+
connectionRef.current = null;
|
|
256
|
+
setConnected(false);
|
|
257
|
+
};
|
|
258
|
+
}, [clientKey, enabled, collections == null ? void 0 : collections.join(",")]);
|
|
259
|
+
return { connected, lastEvent };
|
|
260
|
+
}
|
|
261
|
+
//# sourceMappingURL=realtime.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/realtime.ts","../src/core/query/realtime-hooks.ts","../src/core/query/realtime.ts","../src/core/client/types.ts","../src/core/query/query-keys.ts"],"sourcesContent":["export { useRealtimeQuery } from './core/query/realtime-hooks'\nexport type {\n UseRealtimeQueryOptions,\n UseRealtimeQueryResult,\n RealtimeEvent,\n} from './core/query/realtime-hooks'\nexport { RealtimeConnection, type RealtimeListener } from './core/query/realtime'\n","import { useEffect, useRef, useState } from 'react'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { RealtimeConnection, type RealtimeEvent } from './realtime'\nimport { resolveApiUrl, type PublicCollection } from '../client/types'\nimport { collectionKeys } from './query-keys'\n\nexport type { RealtimeEvent }\n\nexport interface UseRealtimeQueryOptions {\n /** Filter events to specific collections. Empty/undefined = all collections. */\n collections?: PublicCollection[]\n /** Enable/disable the SSE connection. Default: true. */\n enabled?: boolean\n}\n\nexport interface UseRealtimeQueryResult {\n /** Whether the SSE connection is currently active. */\n connected: boolean\n /** The last received event, or null. */\n lastEvent: RealtimeEvent | null\n}\n\n/**\n * React hook that subscribes to real-time collection change events via SSE.\n * Automatically invalidates React Query cache when changes are detected.\n *\n * @example\n * ```tsx\n * const { connected } = useRealtimeQuery({\n * clientKey: 'your-key',\n * getToken: () => client.customer.getToken(),\n * collections: ['products', 'orders'],\n * })\n * ```\n */\nexport function useRealtimeQuery(options: {\n clientKey: string\n getToken: () => string | null\n collections?: PublicCollection[]\n enabled?: boolean\n}): UseRealtimeQueryResult {\n const { clientKey, getToken, collections, enabled = true } = options\n const queryClient = useQueryClient()\n const [connected, setConnected] = useState(false)\n const [lastEvent, setLastEvent] = useState<RealtimeEvent | null>(null)\n const connectionRef = useRef<RealtimeConnection | null>(null)\n\n useEffect(() => {\n if (!enabled || !clientKey) return\n\n const baseUrl = resolveApiUrl()\n const conn = new RealtimeConnection(\n baseUrl,\n clientKey,\n getToken,\n collections,\n )\n connectionRef.current = conn\n\n // Listen for events and invalidate queries\n const removeListener = conn.addListener((event) => {\n setLastEvent(event)\n\n // Invalidate all queries for the changed collection\n const keys = collectionKeys(event.collection as PublicCollection)\n queryClient.invalidateQueries({ queryKey: keys.all })\n })\n\n // Track connection state\n const pollInterval = setInterval(() => {\n setConnected(conn.connected)\n }, 1000)\n\n conn.connect()\n\n return () => {\n conn.disconnect()\n removeListener()\n clearInterval(pollInterval)\n connectionRef.current = null\n setConnected(false)\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [clientKey, enabled, collections?.join(',')])\n\n return { connected, lastEvent }\n}\n","/**\n * Fetch-based SSE connection manager for real-time collection change events.\n * Uses fetch + ReadableStream to support custom auth headers (unlike native EventSource).\n */\n\nexport interface RealtimeEvent {\n collection: string\n operation: string\n id: string | null\n timestamp: string\n}\n\nexport type RealtimeListener = (event: RealtimeEvent) => void\n\nconst INITIAL_RECONNECT_DELAY = 1_000\nconst MAX_RECONNECT_DELAY = 30_000\nconst RECONNECT_BACKOFF_FACTOR = 2\nconst MAX_NO_TOKEN_RETRIES = 5\n\nexport class RealtimeConnection {\n private abortController: AbortController | null = null\n private reconnectAttempt = 0\n private noTokenAttempts = 0\n private reconnectTimer: ReturnType<typeof setTimeout> | null = null\n private listeners = new Set<RealtimeListener>()\n private _connected = false\n\n constructor(\n private baseUrl: string,\n private clientKey: string,\n private getToken: () => string | null,\n private collections?: string[],\n ) {}\n\n get connected(): boolean {\n return this._connected\n }\n\n addListener(fn: RealtimeListener): () => void {\n this.listeners.add(fn)\n return () => this.listeners.delete(fn)\n }\n\n connect(): void {\n if (this.abortController) return // Already connecting/connected\n\n this.abortController = new AbortController()\n this.startStream(this.abortController.signal)\n }\n\n disconnect(): void {\n this._connected = false\n if (this.reconnectTimer) {\n clearTimeout(this.reconnectTimer)\n this.reconnectTimer = null\n }\n if (this.abortController) {\n this.abortController.abort()\n this.abortController = null\n }\n this.reconnectAttempt = 0\n this.noTokenAttempts = 0\n }\n\n private async startStream(signal: AbortSignal): Promise<void> {\n const token = this.getToken()\n if (!token) {\n this.noTokenAttempts++\n if (this.noTokenAttempts >= MAX_NO_TOKEN_RETRIES) {\n // Stop reconnecting — no token available after multiple attempts\n this._connected = false\n this.abortController = null\n return\n }\n this.scheduleReconnect()\n return\n }\n this.noTokenAttempts = 0\n\n const params = this.collections?.length\n ? `?collections=${this.collections.join(',')}`\n : ''\n const url = `${this.baseUrl}/api/events/stream${params}`\n\n try {\n const response = await fetch(url, {\n headers: {\n 'X-Client-Key': this.clientKey,\n Authorization: `Bearer ${token}`,\n },\n signal,\n })\n\n if (!response.ok) {\n if (response.status === 401) {\n // Token expired — try reconnecting (will get fresh token)\n this.scheduleReconnect()\n return\n }\n throw new Error(`SSE connection failed: ${response.status}`)\n }\n\n if (!response.body) {\n throw new Error('SSE response has no body')\n }\n\n this._connected = true\n this.reconnectAttempt = 0\n\n await this.readStream(response.body, signal)\n } catch {\n if (signal.aborted) return // Intentional disconnect\n this._connected = false\n this.scheduleReconnect()\n }\n }\n\n private async readStream(\n body: ReadableStream<Uint8Array>,\n signal: AbortSignal,\n ): Promise<void> {\n const reader = body.getReader()\n const decoder = new TextDecoder()\n let buffer = ''\n let currentEvent = ''\n let currentData = ''\n\n try {\n while (true) {\n const { done, value } = await reader.read()\n if (done || signal.aborted) break\n\n buffer += decoder.decode(value, { stream: true })\n const lines = buffer.split('\\n')\n buffer = lines.pop() ?? '' // Keep incomplete last line in buffer\n\n for (const line of lines) {\n if (line.startsWith('event: ')) {\n currentEvent = line.slice(7)\n } else if (line.startsWith('data: ')) {\n currentData += (currentData ? '\\n' : '') + line.slice(6)\n } else if (line === '') {\n // Empty line = end of event\n if (currentEvent === 'collection:change' && currentData) {\n try {\n const event: RealtimeEvent = JSON.parse(currentData)\n for (const listener of this.listeners) {\n try {\n listener(event)\n } catch {\n // Listener error — ignore\n }\n }\n } catch {\n // Malformed JSON — ignore\n }\n }\n currentEvent = ''\n currentData = ''\n }\n // Ignore comment lines (: heartbeat)\n }\n }\n } catch {\n // Stream read error\n } finally {\n reader.releaseLock()\n this._connected = false\n if (!signal.aborted) {\n this.scheduleReconnect()\n }\n }\n }\n\n private scheduleReconnect(): void {\n if (this.reconnectTimer) return\n\n const delay = Math.min(\n INITIAL_RECONNECT_DELAY *\n Math.pow(RECONNECT_BACKOFF_FACTOR, this.reconnectAttempt),\n MAX_RECONNECT_DELAY,\n )\n this.reconnectAttempt++\n\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = null\n this.abortController = new AbortController()\n this.startStream(this.abortController.signal)\n }, delay)\n }\n}\n","import type { Sort, Where } from 'payload'\n\nimport type { Collection, PublicCollection } from '../collection/const'\n\nexport type { Collection, PublicCollection }\n\n// ============================================================================\n// API URL Configuration\n// ============================================================================\n\ndeclare const __DEFAULT_API_URL__: string\n\n/**\n * API URL을 반환합니다.\n * 환경변수 SOFTWARE_API_URL 또는 NEXT_PUBLIC_SOFTWARE_API_URL로 오버라이드 가능.\n * 빌드 시 버전에 따라 기본값 결정: dev 빌드 → api-dev, 정식 → api.01.software\n */\nexport function resolveApiUrl(): string {\n const envUrl =\n process.env.SOFTWARE_API_URL || process.env.NEXT_PUBLIC_SOFTWARE_API_URL\n if (envUrl) {\n return envUrl.replace(/\\/$/, '')\n }\n return __DEFAULT_API_URL__\n}\n\n// ============================================================================\n// Client Configuration\n// ============================================================================\n\nexport interface ClientBrowserConfig {\n clientKey: string\n /**\n * Customer authentication options.\n * Used to initialize CustomerAuth on BrowserClient.\n */\n customer?: {\n /**\n * Persist token in localStorage. Defaults to `true`.\n * - `true` (default): uses key `'customer-token'`\n * - `string`: uses the given string as localStorage key\n * - `false`: disables persistence (token/onTokenChange used instead)\n *\n * Handles SSR safely (no-op on server).\n * When enabled, `token` and `onTokenChange` are ignored.\n */\n persist?: boolean | string\n /** Initial token (e.g. from SSR cookie) */\n token?: string\n /** Called when token changes (login/logout) — use to persist in localStorage/cookie */\n onTokenChange?: (token: string | null) => void\n }\n}\n\nexport interface ClientServerConfig extends ClientBrowserConfig {\n secretKey: string\n}\n\nexport interface ClientMetadata {\n userAgent?: string\n timestamp: number\n}\n\nexport interface ClientState {\n metadata: ClientMetadata\n}\n\n// ============================================================================\n// API Response Types\n// ============================================================================\n\nexport interface PaginationMeta {\n page: number\n limit: number\n totalDocs: number\n totalPages: number\n hasNextPage: boolean\n hasPrevPage: boolean\n pagingCounter: number\n prevPage: number | null\n nextPage: number | null\n}\n\n// ============================================================================\n// Payload CMS Native Response Types\n// ============================================================================\n\n/**\n * Payload CMS Find (List) Response\n * GET /api/{collection}\n */\nexport interface PayloadFindResponse<T = unknown> {\n docs: T[]\n totalDocs: number\n limit: number\n totalPages: number\n page: number\n pagingCounter: number\n hasPrevPage: boolean\n hasNextPage: boolean\n prevPage: number | null\n nextPage: number | null\n}\n\n/**\n * Payload CMS Create/Update Response\n * POST /api/{collection}\n * PATCH /api/{collection}/{id}\n */\nexport interface PayloadMutationResponse<T = unknown> {\n message: string\n doc: T\n errors?: unknown[]\n}\n\n// ============================================================================\n// Query Options\n// ============================================================================\n\nexport interface ApiQueryOptions {\n page?: number\n limit?: number\n sort?: Sort\n where?: Where\n depth?: number\n select?: Record<string, boolean>\n}\n\nexport interface ApiQueryReactOptions {\n keepPreviousData?: boolean\n}\n\n// ============================================================================\n// Debug & Retry Configuration\n// ============================================================================\n\nexport interface DebugConfig {\n logRequests?: boolean\n logResponses?: boolean\n logErrors?: boolean\n}\n\nexport interface RetryConfig {\n maxRetries?: number\n retryableStatuses?: number[]\n retryDelay?: (attempt: number) => number\n}\n\n\n// ============================================================================\n// Collection Types (re-exported from collection/const)\n// ============================================================================\n\n// ============================================================================\n// Type Utilities\n// ============================================================================\n\nexport type DeepPartial<T> = {\n [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P]\n}\n\nexport type ExtractArrayType<T> = T extends (infer U)[] ? U : never\n","import type { PublicCollection, ApiQueryOptions } from '../client/types'\n\nexport function collectionKeys<T extends PublicCollection>(collection: T) {\n return {\n all: [collection] as const,\n lists: () => [collection, 'list'] as const,\n list: (options?: ApiQueryOptions) => [collection, 'list', options] as const,\n details: () => [collection, 'detail'] as const,\n detail: (id: string, options?: ApiQueryOptions) =>\n [collection, 'detail', id, options] as const,\n infinites: () => [collection, 'infinite'] as const,\n infinite: (options?: Omit<ApiQueryOptions, 'page'>) =>\n [collection, 'infinite', options] as const,\n }\n}\n\nexport const customerKeys = {\n all: ['customer'] as const,\n me: () => ['customer', 'me'] as const,\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { R as RealtimeEvent } from './realtime-DupPIYx-.cjs';
|
|
2
|
+
export { a as RealtimeConnection, b as RealtimeListener } from './realtime-DupPIYx-.cjs';
|
|
3
|
+
import { P as PublicCollection } from './const-BpirbGBD.cjs';
|
|
4
|
+
import './payload-types-CZiaL4Wr.cjs';
|
|
5
|
+
|
|
6
|
+
interface UseRealtimeQueryOptions {
|
|
7
|
+
/** Filter events to specific collections. Empty/undefined = all collections. */
|
|
8
|
+
collections?: PublicCollection[];
|
|
9
|
+
/** Enable/disable the SSE connection. Default: true. */
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface UseRealtimeQueryResult {
|
|
13
|
+
/** Whether the SSE connection is currently active. */
|
|
14
|
+
connected: boolean;
|
|
15
|
+
/** The last received event, or null. */
|
|
16
|
+
lastEvent: RealtimeEvent | null;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* React hook that subscribes to real-time collection change events via SSE.
|
|
20
|
+
* Automatically invalidates React Query cache when changes are detected.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* const { connected } = useRealtimeQuery({
|
|
25
|
+
* clientKey: 'your-key',
|
|
26
|
+
* getToken: () => client.customer.getToken(),
|
|
27
|
+
* collections: ['products', 'orders'],
|
|
28
|
+
* })
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
declare function useRealtimeQuery(options: {
|
|
32
|
+
clientKey: string;
|
|
33
|
+
getToken: () => string | null;
|
|
34
|
+
collections?: PublicCollection[];
|
|
35
|
+
enabled?: boolean;
|
|
36
|
+
}): UseRealtimeQueryResult;
|
|
37
|
+
|
|
38
|
+
export { RealtimeEvent, type UseRealtimeQueryOptions, type UseRealtimeQueryResult, useRealtimeQuery };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { R as RealtimeEvent } from './realtime-DupPIYx-.js';
|
|
2
|
+
export { a as RealtimeConnection, b as RealtimeListener } from './realtime-DupPIYx-.js';
|
|
3
|
+
import { P as PublicCollection } from './const-qZSQiSSC.js';
|
|
4
|
+
import './payload-types-CZiaL4Wr.js';
|
|
5
|
+
|
|
6
|
+
interface UseRealtimeQueryOptions {
|
|
7
|
+
/** Filter events to specific collections. Empty/undefined = all collections. */
|
|
8
|
+
collections?: PublicCollection[];
|
|
9
|
+
/** Enable/disable the SSE connection. Default: true. */
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface UseRealtimeQueryResult {
|
|
13
|
+
/** Whether the SSE connection is currently active. */
|
|
14
|
+
connected: boolean;
|
|
15
|
+
/** The last received event, or null. */
|
|
16
|
+
lastEvent: RealtimeEvent | null;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* React hook that subscribes to real-time collection change events via SSE.
|
|
20
|
+
* Automatically invalidates React Query cache when changes are detected.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* const { connected } = useRealtimeQuery({
|
|
25
|
+
* clientKey: 'your-key',
|
|
26
|
+
* getToken: () => client.customer.getToken(),
|
|
27
|
+
* collections: ['products', 'orders'],
|
|
28
|
+
* })
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
declare function useRealtimeQuery(options: {
|
|
32
|
+
clientKey: string;
|
|
33
|
+
getToken: () => string | null;
|
|
34
|
+
collections?: PublicCollection[];
|
|
35
|
+
enabled?: boolean;
|
|
36
|
+
}): UseRealtimeQueryResult;
|
|
37
|
+
|
|
38
|
+
export { RealtimeEvent, type UseRealtimeQueryOptions, type UseRealtimeQueryResult, useRealtimeQuery };
|