lazypock 0.8.3 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -20
- package/dist/{chunk-V2XSEOWF.js → chunk-CGQVJ7TT.js} +24 -7
- package/dist/chunk-CGQVJ7TT.js.map +1 -0
- package/dist/cli.cjs +23 -6
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.global.js +23 -6
- package/dist/cli.global.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/index.cjs +110 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -8
- package/dist/index.d.ts +65 -8
- package/dist/index.global.js +110 -35
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +88 -30
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/codegen.ts +38 -11
- package/src/collection.ts +77 -9
- package/src/index.ts +1 -1
- package/src/lazypock.ts +10 -0
- package/src/realtime.ts +79 -11
- package/dist/chunk-V2XSEOWF.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
fieldTypeScriptType,
|
|
5
5
|
generateTypes,
|
|
6
6
|
schemaFieldType
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-CGQVJ7TT.js";
|
|
8
8
|
|
|
9
9
|
// src/types.ts
|
|
10
10
|
var ApiError = class extends Error {
|
|
@@ -781,25 +781,24 @@ var CollectionService = class _CollectionService {
|
|
|
781
781
|
derived.fieldsPreset = this.fieldsPreset;
|
|
782
782
|
return derived;
|
|
783
783
|
}
|
|
784
|
-
|
|
785
|
-
/**
|
|
786
|
-
* Subscribe to realtime changes for this collection.
|
|
787
|
-
* The event's `action` is one of `"create" | "update" | "delete"`.
|
|
788
|
-
*
|
|
789
|
-
* Access is governed by the collection's `listRule` (PocketBase semantics):
|
|
790
|
-
* public collections allow anonymous subscriptions; other collections
|
|
791
|
-
* require a matching logged-in user or superuser.
|
|
792
|
-
*
|
|
793
|
-
* @param callback Received on every record change.
|
|
794
|
-
* @param recordId Optional — subscribe to a single record instead of `*`.
|
|
795
|
-
* @returns A function that unsubscribes this callback.
|
|
796
|
-
*/
|
|
797
|
-
subscribe(callback, recordId) {
|
|
784
|
+
subscribe(topicOrCallback, maybeCallback, options) {
|
|
798
785
|
if (!this.realtime) {
|
|
799
786
|
console.warn("[lazypock] No realtime service configured.");
|
|
800
787
|
return () => {
|
|
801
788
|
};
|
|
802
789
|
}
|
|
790
|
+
let recordId;
|
|
791
|
+
let callback;
|
|
792
|
+
let joinPayload;
|
|
793
|
+
if (typeof topicOrCallback === "function") {
|
|
794
|
+
callback = topicOrCallback;
|
|
795
|
+
if (typeof maybeCallback === "string") recordId = maybeCallback;
|
|
796
|
+
} else {
|
|
797
|
+
callback = maybeCallback;
|
|
798
|
+
recordId = topicOrCallback === "*" ? void 0 : topicOrCallback;
|
|
799
|
+
const { headers: _ignored, ...rest } = options ?? {};
|
|
800
|
+
if (Object.keys(rest).length > 0) joinPayload = rest;
|
|
801
|
+
}
|
|
803
802
|
const topic = "collection:" + this.collectionName + (recordId ? ":" + recordId : "");
|
|
804
803
|
const handler = (raw) => {
|
|
805
804
|
const record = raw.payload?.["record"] ?? {};
|
|
@@ -810,15 +809,23 @@ var CollectionService = class _CollectionService {
|
|
|
810
809
|
});
|
|
811
810
|
};
|
|
812
811
|
this.realtime.ensureConnected();
|
|
813
|
-
this.realtime.subscribe(topic, handler);
|
|
812
|
+
this.realtime.subscribe(topic, handler, joinPayload);
|
|
814
813
|
return () => this.realtime?.unsubscribe(topic, handler);
|
|
815
814
|
}
|
|
816
815
|
/**
|
|
817
|
-
* Unsubscribe
|
|
818
|
-
*
|
|
816
|
+
* Unsubscribe from realtime changes (PocketBase-compatible):
|
|
817
|
+
* - `unsubscribe()` — remove **all** subscriptions of this collection
|
|
818
|
+
* - `unsubscribe('*')` — remove wildcard subscriptions
|
|
819
|
+
* - `unsubscribe('RECORD_ID')` — remove that record's subscriptions
|
|
819
820
|
*/
|
|
820
821
|
unsubscribe(recordId) {
|
|
821
|
-
|
|
822
|
+
if (recordId === void 0) {
|
|
823
|
+
this.realtime?.unsubscribeByPrefix(
|
|
824
|
+
"collection:" + this.collectionName
|
|
825
|
+
);
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
const topic = "collection:" + this.collectionName + (recordId === "*" ? "" : ":" + recordId);
|
|
822
829
|
this.realtime?.unsubscribe(topic);
|
|
823
830
|
}
|
|
824
831
|
// ── Auth Collection Methods ──
|
|
@@ -885,6 +892,7 @@ var RealtimeService = class {
|
|
|
885
892
|
this.reconnectAttempt = 0;
|
|
886
893
|
this.maxReconnectDelay = 5e3;
|
|
887
894
|
this.url = "";
|
|
895
|
+
this.tokenProvider = null;
|
|
888
896
|
// ── Heartbeat ──
|
|
889
897
|
this.heartbeatInterval = null;
|
|
890
898
|
}
|
|
@@ -910,6 +918,32 @@ var RealtimeService = class {
|
|
|
910
918
|
setUrl(url) {
|
|
911
919
|
this.url = url;
|
|
912
920
|
}
|
|
921
|
+
/**
|
|
922
|
+
* Register a token provider consulted at every (re)connect.
|
|
923
|
+
* When set, it takes precedence over the token passed to {@link connect}.
|
|
924
|
+
*/
|
|
925
|
+
setTokenProvider(provider) {
|
|
926
|
+
this.tokenProvider = provider;
|
|
927
|
+
}
|
|
928
|
+
/**
|
|
929
|
+
* Reconnect the socket immediately with the current token.
|
|
930
|
+
* Called by the SDK when auth changes (login/logout/token refresh) so
|
|
931
|
+
* private-channel joins are authorized with the new credentials. No-op
|
|
932
|
+
* when the socket has never been opened and nothing is subscribed.
|
|
933
|
+
*/
|
|
934
|
+
refresh() {
|
|
935
|
+
if (typeof WebSocket === "undefined") return;
|
|
936
|
+
if (!this.ws && this.subscriptions.size === 0) return;
|
|
937
|
+
this.clearReconnectTimer();
|
|
938
|
+
const ws = this.ws;
|
|
939
|
+
this.ws = null;
|
|
940
|
+
if (ws) {
|
|
941
|
+
ws.onclose = null;
|
|
942
|
+
ws.close();
|
|
943
|
+
}
|
|
944
|
+
this.reconnectAttempt = 0;
|
|
945
|
+
this.doConnect();
|
|
946
|
+
}
|
|
913
947
|
/*
|
|
914
948
|
* Ensure the socket is connected, then subscribe.
|
|
915
949
|
* Used by collection-level convenience wrappers so a connection is opened
|
|
@@ -933,15 +967,30 @@ var RealtimeService = class {
|
|
|
933
967
|
this.ws = null;
|
|
934
968
|
}
|
|
935
969
|
/**
|
|
936
|
-
* Subscribe to a topic (e.g. "collection:posts" or "
|
|
970
|
+
* Subscribe to a topic (e.g. "collection:posts" or "custom:chat-room").
|
|
937
971
|
* The backend Channel authorizes via listRule on join.
|
|
972
|
+
*
|
|
973
|
+
* @param joinPayload Optional payload forwarded with the channel join
|
|
974
|
+
* (available to the server's join callback / hooks, e.g. `expand`).
|
|
938
975
|
*/
|
|
939
|
-
subscribe(topic, callback) {
|
|
976
|
+
subscribe(topic, callback, joinPayload) {
|
|
940
977
|
const subs = this.subscriptions.get(topic) || [];
|
|
941
|
-
subs.push({ topic, callback });
|
|
978
|
+
subs.push({ topic, callback, joinPayload });
|
|
942
979
|
this.subscriptions.set(topic, subs);
|
|
943
980
|
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
944
|
-
this.joinTopic(topic);
|
|
981
|
+
this.joinTopic(topic, joinPayload);
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
/**
|
|
985
|
+
* Remove all subscriptions for topics under `prefix` (the topic itself or
|
|
986
|
+
* any topic starting with `prefix + ":"`). Used by collection-level
|
|
987
|
+
* `unsubscribe()` to drop every subscription of a collection.
|
|
988
|
+
*/
|
|
989
|
+
unsubscribeByPrefix(prefix) {
|
|
990
|
+
for (const topic of [...this.subscriptions.keys()]) {
|
|
991
|
+
if (topic === prefix || topic.startsWith(prefix + ":")) {
|
|
992
|
+
this.subscriptions.delete(topic);
|
|
993
|
+
}
|
|
945
994
|
}
|
|
946
995
|
}
|
|
947
996
|
/**
|
|
@@ -960,9 +1009,14 @@ var RealtimeService = class {
|
|
|
960
1009
|
}
|
|
961
1010
|
}
|
|
962
1011
|
resubscribeAll() {
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
1012
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1013
|
+
for (const entries of this.subscriptions.values()) {
|
|
1014
|
+
for (const entry of entries) {
|
|
1015
|
+
if (seen.has(entry.topic)) continue;
|
|
1016
|
+
seen.add(entry.topic);
|
|
1017
|
+
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
1018
|
+
this.joinTopic(entry.topic, entry.joinPayload);
|
|
1019
|
+
}
|
|
966
1020
|
}
|
|
967
1021
|
}
|
|
968
1022
|
}
|
|
@@ -974,8 +1028,9 @@ var RealtimeService = class {
|
|
|
974
1028
|
return;
|
|
975
1029
|
}
|
|
976
1030
|
let url = this.url;
|
|
977
|
-
|
|
978
|
-
|
|
1031
|
+
const token = this.tokenProvider ? this.tokenProvider() : this.token;
|
|
1032
|
+
if (token) {
|
|
1033
|
+
url += (url.includes("?") ? "&" : "?") + "token=" + encodeURIComponent(token);
|
|
979
1034
|
}
|
|
980
1035
|
this.ws = new WebSocket(url);
|
|
981
1036
|
this.ws.onopen = () => {
|
|
@@ -1022,12 +1077,12 @@ var RealtimeService = class {
|
|
|
1022
1077
|
}
|
|
1023
1078
|
}
|
|
1024
1079
|
}
|
|
1025
|
-
joinTopic(topic) {
|
|
1080
|
+
joinTopic(topic, joinPayload) {
|
|
1026
1081
|
const ref = this.nextRef();
|
|
1027
1082
|
const msg = JSON.stringify({
|
|
1028
1083
|
topic,
|
|
1029
1084
|
event: "phx_join",
|
|
1030
|
-
payload: {},
|
|
1085
|
+
payload: joinPayload ?? {},
|
|
1031
1086
|
ref
|
|
1032
1087
|
});
|
|
1033
1088
|
this.ws?.send(msg);
|
|
@@ -1333,6 +1388,9 @@ var LazypockClient = class {
|
|
|
1333
1388
|
if (!options.realtime) {
|
|
1334
1389
|
this.realtime.setUrl(wsUrlFromBaseUrl(baseUrl));
|
|
1335
1390
|
}
|
|
1391
|
+
this.realtime.setTokenProvider(() => this.authStore.token);
|
|
1392
|
+
this.authStore.onChange(() => this.realtime.refresh());
|
|
1393
|
+
this.authReady.then(() => this.realtime.refresh());
|
|
1336
1394
|
this.files = new FilesService(this.http);
|
|
1337
1395
|
this.collections = new CollectionsService(this.http, this.realtime);
|
|
1338
1396
|
if (options.types?.schemas) {
|