prostgles-client 4.0.137 → 4.0.139

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/lib/prostgles.ts CHANGED
@@ -10,9 +10,6 @@ import type {
10
10
  AuthGuardLocationResponse,
11
11
  ClientSchema,
12
12
  ClientSyncHandles,
13
- DBEventHandles,
14
- DBNoticeConfig,
15
- DBNotifConfig,
16
13
  DBSchema,
17
14
  DBSchemaTable,
18
15
  DbJoinMaker,
@@ -24,30 +21,31 @@ import type {
24
21
  SQLHandler,
25
22
  SQLResult,
26
23
  SelectParams,
27
- SocketSQLStreamClient,
28
- SocketSQLStreamServer,
29
24
  SubscribeParams,
30
25
  SubscriptionChannels,
31
26
  SubscriptionHandler,
32
27
  TableHandler,
33
28
  UpdateParams,
34
- ViewHandler,
29
+ ViewHandler
35
30
  } from "prostgles-types";
36
31
 
37
32
  import {
33
+ CHANNELS,
38
34
  asName,
39
35
  getJoinHandlers,
40
36
  getKeys,
41
37
  isObject,
42
38
  omitKeys,
43
- CHANNELS,
44
39
  } from "prostgles-types";
45
40
 
46
- import type { SyncDataItem, SyncOneOptions, SyncOptions, SyncedTable, DbTableSync, Sync, SyncOne } from "./SyncedTable/SyncedTable";
47
41
  import { isEqual, useFetch, useSubscribe, useSync } from "./react-hooks";
42
+ import { SQL } from "./SQL";
43
+ import type { DbTableSync, Sync, SyncDataItem, SyncOne, SyncOneOptions, SyncOptions, SyncedTable } from "./SyncedTable/SyncedTable";
44
+ import { FunctionQueuer } from "./FunctionQueuer";
45
+ import { type AuthHandler, setupAuth } from "./Auth";
48
46
 
49
47
  const DEBUG_KEY = "DEBUG_SYNCEDTABLE";
50
- const hasWnd = typeof window !== "undefined";
48
+ export const hasWnd = typeof window !== "undefined";
51
49
  export const debug: any = function (...args: any[]) {
52
50
  if (hasWnd && (window as any)[DEBUG_KEY]) {
53
51
  (window as any)[DEBUG_KEY](...args);
@@ -56,8 +54,8 @@ export const debug: any = function (...args: any[]) {
56
54
 
57
55
  export { MethodHandler, SQLResult, asName };
58
56
 
59
- export * from "./react-hooks";
60
- export * from "./useProstglesClient";
57
+ export * from "./react-hooks";
58
+ export * from "./useProstglesClient";
61
59
 
62
60
 
63
61
  export type ViewHandlerClient<T extends AnyObject = AnyObject, S extends DBSchema | void = void> = ViewHandler<T, S> & {
@@ -168,7 +166,7 @@ export type InitOptions<DBSchema = void> = {
168
166
  * true by default
169
167
  */
170
168
  onSchemaChange?: false | (() => void);
171
- onReady: (dbo: DBHandlerClient<DBSchema>, methods: MethodHandler | undefined, tableSchema: DBSchemaTable[] | undefined, auth: Auth | undefined, isReconnect: boolean) => any;
169
+ onReady: (dbo: DBHandlerClient<DBSchema>, methods: MethodHandler | undefined, tableSchema: DBSchemaTable[] | undefined, auth: AuthHandler, isReconnect: boolean) => any;
172
170
 
173
171
  /**
174
172
  * If not provided will fire onReady
@@ -239,82 +237,8 @@ export function prostgles<DBSchema>(initOpts: InitOptions<DBSchema>, syncedTable
239
237
  let syncedTables: Record<string, any> = {};
240
238
 
241
239
  let syncs: Syncs = {};
242
-
243
- const notifSubs: {
244
- [key: string]: {
245
- config: DBNotifConfig
246
- listeners: ((notif: any) => void)[]
247
- }
248
- } = {};
249
- const removeNotifListener = (listener: any, conf: DBNotifConfig) => {
250
- const channelSubs = notifSubs[conf.notifChannel]
251
- if (channelSubs) {
252
- channelSubs.listeners = channelSubs.listeners.filter(nl => nl !== listener);
253
- if (!channelSubs.listeners.length && channelSubs.config.socketUnsubChannel && socket) {
254
- socket.emit(channelSubs.config.socketUnsubChannel, {});
255
- delete notifSubs[conf.notifChannel];
256
- }
257
- }
258
- };
259
- const addNotifListener = (listener: any, conf: DBNotifConfig) => {
260
-
261
- const channelSubs = notifSubs[conf.notifChannel]
262
- if (!channelSubs) {
263
- notifSubs[conf.notifChannel] = {
264
- config: conf,
265
- listeners: [listener]
266
- };
267
- socket.removeAllListeners(conf.socketChannel);
268
- socket.on(conf.socketChannel, (notif: any) => {
269
- if (notifSubs[conf.notifChannel]?.listeners.length) {
270
- notifSubs[conf.notifChannel]!.listeners.map(l => {
271
- l(notif);
272
- })
273
- } else {
274
- socket.emit(notifSubs[conf.notifChannel]?.config.socketUnsubChannel, {});
275
- }
276
- });
277
-
278
- } else {
279
- notifSubs[conf.notifChannel]?.listeners.push(listener);
280
- }
281
- };
282
-
283
-
284
- let noticeSubs: {
285
- listeners: ((notice: any) => void)[];
286
- config: DBNoticeConfig;
287
- } | undefined;
288
- const removeNoticeListener = (listener: any) => {
289
- if (noticeSubs) {
290
- noticeSubs.listeners = noticeSubs.listeners.filter(nl => nl !== listener);
291
- if (!noticeSubs.listeners.length && noticeSubs.config.socketUnsubChannel && socket) {
292
- socket.emit(noticeSubs.config.socketUnsubChannel, {});
293
- }
294
- }
295
- };
296
- const addNoticeListener = (listener: any, conf: DBNoticeConfig) => {
297
- noticeSubs ??= {
298
- config: conf,
299
- listeners: []
300
- };
301
-
302
- if (!noticeSubs.listeners.length) {
303
- socket.removeAllListeners(conf.socketChannel);
304
- socket.on(conf.socketChannel, (notice: any) => {
305
- if (noticeSubs && noticeSubs.listeners.length) {
306
- noticeSubs.listeners.map(l => {
307
- l(notice);
308
- })
309
- } else {
310
- socket.emit(conf.socketUnsubChannel, {});
311
- }
312
- });
313
- }
314
- noticeSubs.listeners.push(listener);
315
- };
316
-
317
240
  let state: undefined | "connected" | "disconnected" | "reconnected";
241
+ const sql = new SQL()
318
242
 
319
243
  const destroySyncs = async () => {
320
244
  debug("destroySyncs", { subscriptions, syncedTables });
@@ -643,7 +567,7 @@ export function prostgles<DBSchema>(initOpts: InitOptions<DBSchema>, syncedTable
643
567
 
644
568
  /* Schema = published schema */
645
569
  socket.on(CHANNELS.SCHEMA, async ({ joinTables = [], ...clientSchema }: ClientSchema) => {
646
- const { schema, methods, tableSchema, auth, rawSQL, err } = clientSchema;
570
+ const { schema, methods, tableSchema, auth: authConfig, rawSQL, err } = clientSchema;
647
571
  /** Only destroy existing syncs if schema changed */
648
572
  const schemaDidNotChange = schemaAge?.clientSchema && isEqual(schemaAge.clientSchema, clientSchema)
649
573
  if(!schemaDidNotChange){
@@ -671,42 +595,8 @@ export function prostgles<DBSchema>(initOpts: InitOptions<DBSchema>, syncedTable
671
595
  const dbo: Partial<DBHandlerClient> = JSON.parse(JSON.stringify(schema));
672
596
  const _methods: typeof methods = JSON.parse(JSON.stringify(methods));
673
597
  let methodsObj: MethodHandler = {};
674
- let _auth = {};
675
-
676
- if(auth){
677
- if (auth.pathGuard && hasWnd) {
678
- const doReload = (res?: AuthGuardLocationResponse) => {
679
- if (res?.shouldReload) {
680
- if (onReload) onReload();
681
- else if (typeof window !== "undefined") {
682
- window.location.reload();
683
- }
684
- }
685
- }
686
- socket.emit(CHANNELS.AUTHGUARD, JSON.stringify(window.location as AuthGuardLocation), (err: any, res: AuthGuardLocationResponse) => {
687
- doReload(res)
688
- });
689
-
690
- socket.removeAllListeners(CHANNELS.AUTHGUARD);
691
- socket.on(CHANNELS.AUTHGUARD, (res: AuthGuardLocationResponse) => {
692
- doReload(res);
693
- });
694
- }
695
-
696
- _auth = { ...auth };
697
- [CHANNELS.LOGIN, CHANNELS.LOGOUT, CHANNELS.REGISTER].map(funcName => {
698
- if (auth[funcName]) {
699
- _auth[funcName] = function (params) {
700
- return new Promise((resolve, reject) => {
701
- socket.emit(preffix + funcName, params, (err, res) => {
702
- if (err) reject(err);
703
- else resolve(res);
704
- });
705
- });
706
- }
707
- }
708
- });
709
- }
598
+
599
+ const auth = setupAuth({ authData: authConfig, socket, onReload });
710
600
 
711
601
  _methods.map(method => {
712
602
  /** New method def */
@@ -729,99 +619,7 @@ export function prostgles<DBSchema>(initOpts: InitOptions<DBSchema>, syncedTable
729
619
  methodsObj = Object.freeze(methodsObj);
730
620
 
731
621
  if (rawSQL) {
732
- dbo.sql = function (query, params, options) {
733
- return new Promise((resolve, reject) => {
734
- socket.emit(CHANNELS.SQL, { query, params, options }, (err, res) => {
735
- if (err) reject(err);
736
- else {
737
- if(options?.returnType === "stream"){
738
- const { channel, unsubChannel } = res as SocketSQLStreamServer;
739
- const start: SocketSQLStreamClient["start"] = (listener) => new Promise<Awaited<ReturnType<SocketSQLStreamClient["start"]>>>((resolveStart, rejectStart) => {
740
- socket.on(channel, listener)
741
- socket.emit(channel, {}, (pid: number, err) => {
742
- if(err){
743
- rejectStart(err);
744
- socket.removeAllListeners(channel);
745
- } else {
746
- resolveStart({
747
- pid,
748
- run: (query, params) => {
749
- return new Promise((resolveRun, rejectRun) => {
750
- socket.emit(channel, { query, params }, (data, _err) => {
751
- if(_err){
752
- rejectRun(_err);
753
- } else {
754
- resolveRun(data);
755
- }
756
- });
757
- });
758
- },
759
- stop: (terminate?: boolean) => {
760
- return new Promise((resolveStop, rejectStop) => {
761
- socket.emit(unsubChannel, { terminate }, (data, _err) => {
762
- if(_err){
763
- rejectStop(_err);
764
- } else {
765
- resolveStop(data);
766
- }
767
- });
768
- });
769
- }
770
- });
771
- }
772
- });
773
- });
774
- const streamHandlers = {
775
- channel,
776
- unsubChannel,
777
- start,
778
- } satisfies SocketSQLStreamClient;
779
-
780
- return resolve(streamHandlers as any);
781
- } else if (options &&
782
- (options.returnType === "noticeSubscription") &&
783
- res &&
784
- Object.keys(res).sort().join() === ["socketChannel", "socketUnsubChannel"].sort().join() &&
785
- !Object.values(res).find(v => typeof v !== "string")
786
- ) {
787
- const sockInfo: DBNoticeConfig = res;
788
- const addListener = (listener: (arg: any) => void) => {
789
- addNoticeListener(listener, sockInfo);
790
- return {
791
- ...sockInfo,
792
- removeListener: () => removeNoticeListener(listener)
793
- }
794
- };
795
- const handle: DBEventHandles = {
796
- ...sockInfo,
797
- addListener
798
- };
799
- // @ts-ignore
800
- resolve(handle);
801
- } else if (
802
- (!options || !options.returnType || options.returnType !== "statement") &&
803
- res &&
804
- Object.keys(res).sort().join() === ["socketChannel", "socketUnsubChannel", "notifChannel"].sort().join() &&
805
- !Object.values(res).find(v => typeof v !== "string")
806
- ) {
807
- const sockInfo: DBNotifConfig = res;
808
- const addListener = (listener: (arg: any) => void) => {
809
- addNotifListener(listener, sockInfo)
810
- return {
811
- ...res,
812
- removeListener: () => removeNotifListener(listener, sockInfo)
813
- }
814
- }
815
- const handle: DBEventHandles = { ...res, addListener };
816
- resolve(handle as any);
817
-
818
- } else {
819
- resolve(res);
820
- }
821
- }
822
- });
823
- });
824
- }
622
+ sql.setup({ dbo, socket });
825
623
  }
826
624
 
827
625
  /* Building DBO object */
@@ -989,7 +787,7 @@ export function prostgles<DBSchema>(initOpts: InitOptions<DBSchema>, syncedTable
989
787
 
990
788
  (async () => {
991
789
  try {
992
- await onReady(dbo as DBHandlerClient<DBSchema>, methodsObj, tableSchema, _auth, isReconnect);
790
+ await onReady(dbo as DBHandlerClient<DBSchema>, methodsObj, tableSchema, auth, isReconnect);
993
791
  } catch (err) {
994
792
  console.error("Prostgles: Error within onReady: \n", err);
995
793
  reject(err);
@@ -1001,74 +799,3 @@ export function prostgles<DBSchema>(initOpts: InitOptions<DBSchema>, syncedTable
1001
799
  });
1002
800
  })
1003
801
  }
1004
-
1005
- type Func = (...args: any[]) => any;
1006
- class FunctionQueuer<F extends Func> {
1007
- private queue: { arguments: Parameters<F>; onResult: (result: ReturnType<F>) => void; onFail: (error: any) => void }[] = [];
1008
- private func: F;
1009
- private groupBy?: (args: Parameters<F>) => string;
1010
- constructor(func: F, groupBy?: ((args: Parameters<F>) => string)) {
1011
- this.func = func;
1012
- this.groupBy = groupBy;
1013
- }
1014
- private isRunning = false;
1015
- async run(args: Parameters<F>): Promise<ReturnType<F>> {
1016
-
1017
- const result = new Promise<ReturnType<F>>((resolve, reject) => {
1018
- const item = { arguments: args, onResult: resolve, onFail: reject }
1019
- this.queue.push(item);
1020
- });
1021
-
1022
- const startQueueJob = async () => {
1023
- if (this.isRunning) {
1024
- return;
1025
- }
1026
- this.isRunning = true;
1027
-
1028
- const runItem = async (item: undefined | typeof this.queue[number]) => {
1029
- if (item) {
1030
- try {
1031
- const result = await this.func(...item.arguments);
1032
- item.onResult(result);
1033
- } catch(error) {
1034
- item.onFail(error);
1035
- }
1036
- }
1037
- }
1038
-
1039
- if(!this.groupBy){
1040
- const item = this.queue.shift();
1041
- await runItem(item);
1042
-
1043
- /** Run items in parallel for each group */
1044
- } else {
1045
- type Item = typeof this.queue[number];
1046
- const groups: string[] = [];
1047
- const items: { index: number; item: Item; }[] = [];
1048
- this.queue.forEach(async (item, index) => {
1049
- const group = this.groupBy!(item.arguments);
1050
- if(!groups.includes(group)){
1051
- groups.push(group);
1052
- items.push({ index, item });
1053
- }
1054
- });
1055
- items.slice(0).reverse().forEach((item) => {
1056
- this.queue.splice(item.index, 1);
1057
- });
1058
- await Promise.all(items.map(item => {
1059
- return runItem(item.item);
1060
- }));
1061
- }
1062
-
1063
- this.isRunning = false;
1064
- if (this.queue.length) {
1065
- startQueueJob();
1066
- }
1067
- }
1068
-
1069
- startQueueJob();
1070
-
1071
- return result;
1072
-
1073
- }
1074
- }
@@ -15,12 +15,13 @@ import type { ManagerOptions, Socket, SocketOptions } from "socket.io-client";
15
15
  import { SyncedTable } from "./SyncedTable/SyncedTable";
16
16
  import { prostgles, type Auth, type DBHandlerClient, type InitOptions } from "./prostgles";
17
17
  import { getIO, getReact, useAsyncEffectQueue, useIsMounted } from "./react-hooks";
18
+ import type { AuthHandler } from "./Auth";
18
19
 
19
20
  type OnReadyParams<DBSchema> = {
20
21
  dbo: DBHandlerClient<DBSchema>;
21
22
  methods: MethodHandler | undefined;
22
23
  tableSchema: DBSchemaTable[] | undefined;
23
- auth: Auth | undefined;
24
+ auth: AuthHandler | undefined;
24
25
  isReconnect: boolean;
25
26
  socket: Socket;
26
27
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prostgles-client",
3
- "version": "4.0.137",
3
+ "version": "4.0.139",
4
4
  "description": "Reactive client for Postgres",
5
5
  "main": "dist/prostgles-full.js",
6
6
  "types": "dist/prostgles-full.d.ts",
@@ -28,14 +28,14 @@
28
28
  "pushpublish": "npm version patch --git-tag-version false && git push && npm publish"
29
29
  },
30
30
  "dependencies": {
31
- "prostgles-types": "^4.0.88"
31
+ "prostgles-types": "^4.0.91"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/node": "^14.14.14",
35
35
  "@types/react": "^18.2.19",
36
- "@typescript-eslint/eslint-plugin": "^5.62.0",
37
- "@typescript-eslint/parser": "^5.62.0",
38
- "eslint": "^8.57.0",
36
+ "@typescript-eslint/eslint-plugin": "^8.15.0",
37
+ "@typescript-eslint/parser": "^8.15.0",
38
+ "eslint": "^8.51.0",
39
39
  "eslint-plugin-react-hooks": "^4.6.0",
40
40
  "ts-loader": "^9.5.1",
41
41
  "tsconfig-paths-webpack-plugin": "^4.0.0",
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "peerDependencies": {
47
47
  "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
48
- "socket.io-client": "^4.7.0 || ^4.7.5"
48
+ "socket.io-client": "^4.8.1"
49
49
  },
50
50
  "peerDependenciesMeta": {
51
51
  "react": {
@@ -17,27 +17,27 @@
17
17
  },
18
18
  "..": {
19
19
  "name": "prostgles-client",
20
- "version": "4.0.135",
20
+ "version": "4.0.138",
21
21
  "license": "MIT",
22
22
  "dependencies": {
23
- "prostgles-types": "^4.0.87"
23
+ "prostgles-types": "^4.0.91"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@types/node": "^14.14.14",
27
27
  "@types/react": "^18.2.19",
28
- "@typescript-eslint/eslint-plugin": "^5.62.0",
29
- "@typescript-eslint/parser": "^5.62.0",
30
- "eslint": "^8.57.0",
28
+ "@typescript-eslint/eslint-plugin": "^8.15.0",
29
+ "@typescript-eslint/parser": "^8.15.0",
30
+ "eslint": "^8.51.0",
31
31
  "eslint-plugin-react-hooks": "^4.6.0",
32
32
  "ts-loader": "^9.5.1",
33
33
  "tsconfig-paths-webpack-plugin": "^4.0.0",
34
34
  "typescript": "^5.3.3",
35
- "webpack": "^5.76.2",
36
- "webpack-cli": "^4.9.2"
35
+ "webpack": "^5.94.0",
36
+ "webpack-cli": "^5.1.4"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
40
- "socket.io-client": "^4.7.0 || ^4.7.5"
40
+ "socket.io-client": "^4.8.1"
41
41
  },
42
42
  "peerDependenciesMeta": {
43
43
  "react": {
package/tsconfig.json CHANGED
@@ -24,10 +24,8 @@
24
24
  // "moduleResolution": "node"
25
25
  "declaration": true,
26
26
  "declarationMap": true,
27
- "keyofStringsOnly": true,
28
27
  "ignoreDeprecations": "5.0",
29
28
  "skipLibCheck": true,
30
- /** TODO */
31
29
  "noUncheckedIndexedAccess": true
32
30
  },
33
31
  "include": ["lib"],
@@ -1,9 +0,0 @@
1
- /**
2
- * @license React
3
- * react.production.min.js
4
- *
5
- * Copyright (c) Facebook, Inc. and its affiliates.
6
- *
7
- * This source code is licensed under the MIT license found in the
8
- * LICENSE file in the root directory of this source tree.
9
- */
@@ -1,9 +0,0 @@
1
- /**
2
- * @license React
3
- * react.production.min.js
4
- *
5
- * Copyright (c) Facebook, Inc. and its affiliates.
6
- *
7
- * This source code is licensed under the MIT license found in the
8
- * LICENSE file in the root directory of this source tree.
9
- */