@electric-sql/react 0.0.5 → 0.0.7

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.
@@ -1,5 +1,5 @@
1
+ import { JsonSerializable, Shape, ShapeStream, ShapeStreamOptions } from '@electric-sql/next';
1
2
  import React from 'react';
2
- import { Shape, ShapeStream, ShapeStreamOptions, JsonSerializable } from '@electric-sql/next';
3
3
  interface ShapeContextType {
4
4
  getShape: (shapeStream: ShapeStream) => Shape;
5
5
  getShapeStream: (options: ShapeStreamOptions) => ShapeStream;
@@ -16,9 +16,11 @@ export declare function useShapeContext(): ShapeContextType;
16
16
  interface UseShapeResult {
17
17
  /**
18
18
  * The array of rows that make up the Shape.
19
- * @type {JsonSerializable}
19
+ * @type {{ [key: string]: JsonSerializable }[]}
20
20
  */
21
- data: JsonSerializable[];
21
+ data: {
22
+ [key: string]: JsonSerializable;
23
+ }[];
22
24
  /**
23
25
  * The Shape instance used by this useShape
24
26
  * @type(Shape)
@@ -31,5 +33,8 @@ interface UseShapeResult {
31
33
  */
32
34
  isUpToDate: boolean;
33
35
  }
34
- export declare function useShape(options: ShapeStreamOptions): UseShapeResult;
36
+ interface UseShapeOptions<Selection> extends ShapeStreamOptions {
37
+ selector?: (value: UseShapeResult) => Selection;
38
+ }
39
+ export declare function useShape<Selection = UseShapeResult>({ selector, ...options }: UseShapeOptions<Selection>): Selection;
35
40
  export {};
@@ -33,11 +33,12 @@ var __async = (__this, __arguments, generator) => {
33
33
  step((generator = generator.apply(__this, __arguments)).next());
34
34
  });
35
35
  };
36
- import React, { createContext, useEffect, useContext, useState } from "react";
37
36
  import {
38
37
  Shape,
39
38
  ShapeStream
40
39
  } from "@electric-sql/next";
40
+ import React, { createContext, useCallback, useContext, useRef } from "react";
41
+ import { useSyncExternalStoreWithSelector } from "use-sync-external-store/with-selector";
41
42
  const ShapesContext = createContext(null);
42
43
  const streamCache = /* @__PURE__ */ new Map();
43
44
  const shapeCache = /* @__PURE__ */ new Map();
@@ -91,31 +92,45 @@ function useShapeContext() {
91
92
  }
92
93
  return context;
93
94
  }
94
- function useShape(options) {
95
- const { getShape: getShape2, getShapeStream: getShapeStream2 } = useShapeContext();
96
- const shapeStream = getShapeStream2(options);
97
- const shape = getShape2(shapeStream);
98
- const [shapeData, setShapeData] = useState({
95
+ function shapeSubscribe(shape, callback) {
96
+ const unsubscribe = shape.subscribe(callback);
97
+ return () => {
98
+ unsubscribe();
99
+ };
100
+ }
101
+ function parseShapeData(shape) {
102
+ return {
99
103
  data: [...shape.valueSync.values()],
100
104
  isUpToDate: shape.isUpToDate,
101
105
  isError: shape.error !== false,
102
106
  shape,
103
107
  error: shape.error
104
- });
105
- useEffect(() => {
106
- const unsubscribe = shape.subscribe((map) => {
107
- setShapeData({
108
- data: [...map.values()],
109
- isUpToDate: shape.isUpToDate,
110
- isError: shape.error !== false,
111
- shape,
112
- error: shape.error
113
- });
114
- });
115
- return () => {
116
- unsubscribe();
117
- };
118
- }, []);
108
+ };
109
+ }
110
+ const identity = (arg) => arg;
111
+ function useShape(_a) {
112
+ var _b = _a, {
113
+ selector = identity
114
+ } = _b, options = __objRest(_b, [
115
+ "selector"
116
+ ]);
117
+ const { getShape: getShape2, getShapeStream: getShapeStream2 } = useShapeContext();
118
+ const shapeStream = getShapeStream2(options);
119
+ const shape = getShape2(shapeStream);
120
+ const latestShapeData = useRef(parseShapeData(shape));
121
+ const getSnapshot = React.useCallback(() => latestShapeData.current, []);
122
+ const shapeData = useSyncExternalStoreWithSelector(
123
+ useCallback(
124
+ (onStoreChange) => shapeSubscribe(shape, () => {
125
+ latestShapeData.current = parseShapeData(shape);
126
+ onStoreChange();
127
+ }),
128
+ [shape]
129
+ ),
130
+ getSnapshot,
131
+ getSnapshot,
132
+ selector
133
+ );
119
134
  return shapeData;
120
135
  }
121
136
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react-hooks.tsx"],"sourcesContent":["import React, { createContext, useEffect, useContext, useState } from 'react'\nimport {\n Shape,\n ShapeStream,\n ShapeStreamOptions,\n JsonSerializable,\n} from '@electric-sql/next'\n\ninterface ShapeContextType {\n getShape: (shapeStream: ShapeStream) => Shape\n getShapeStream: (options: ShapeStreamOptions) => ShapeStream\n}\n\n// Create a Context\nconst ShapesContext = createContext<ShapeContextType | null>(null)\n\nconst streamCache = new Map<string, ShapeStream>()\nconst shapeCache = new Map<ShapeStream, Shape>()\n\nexport async function preloadShape(\n options: ShapeStreamOptions\n): Promise<Shape> {\n const shapeStream = getShapeStream(options)\n const shape = getShape(shapeStream)\n await shape.value\n return shape\n}\n\nexport function sortedOptionsHash(options: ShapeStreamOptions): string {\n const shapeDef = JSON.stringify(\n options.shape,\n Object.keys(options.shape).sort()\n )\n // eslint-disable-next-line\n const { shape, ...optionsWithoutShapeDef } = options\n const allOptions = JSON.stringify(\n optionsWithoutShapeDef,\n Object.keys(options).sort()\n )\n const shapeHash = shapeDef + allOptions\n\n return shapeHash\n}\n\nexport function getShapeStream(options: ShapeStreamOptions): ShapeStream {\n const shapeHash = sortedOptionsHash(options)\n\n // If the stream is already cached, return\n if (streamCache.has(shapeHash)) {\n // Return the ShapeStream\n return streamCache.get(shapeHash)!\n } else {\n const newShapeStream = new ShapeStream(options)\n\n streamCache.set(shapeHash, newShapeStream)\n\n // Return the created shape\n return newShapeStream\n }\n}\n\nexport function getShape(shapeStream: ShapeStream): Shape {\n // If the stream is already cached, return\n if (shapeCache.has(shapeStream)) {\n // Return the ShapeStream\n return shapeCache.get(shapeStream)!\n } else {\n const newShape = new Shape(shapeStream)\n\n shapeCache.set(shapeStream, newShape)\n\n // Return the created shape\n return newShape\n }\n}\n\ninterface ShapeProviderProps {\n children: React.ReactNode\n}\n\n// Shapes Provider Component\nexport function ShapesProvider({ children }: ShapeProviderProps): JSX.Element {\n // Provide the context value\n return (\n <ShapesContext.Provider value={{ getShape, getShapeStream }}>\n {children}\n </ShapesContext.Provider>\n )\n}\n\nexport function useShapeContext() {\n const context = useContext(ShapesContext)\n if (!context) {\n throw new Error(`useShapeContext must be used within a ShapeProvider`)\n }\n return context\n}\n\ninterface UseShapeResult {\n /**\n * The array of rows that make up the Shape.\n * @type {JsonSerializable}\n */\n data: JsonSerializable[]\n /**\n * The Shape instance used by this useShape\n * @type(Shape)\n */\n shape: Shape\n error: Shape[`error`]\n isError: boolean\n /**\n * Has the ShapeStream caught up with the replication log from Postgres.\n */\n isUpToDate: boolean\n}\n\nexport function useShape(options: ShapeStreamOptions): UseShapeResult {\n const { getShape, getShapeStream } = useShapeContext()\n const shapeStream = getShapeStream(options)\n const shape = getShape(shapeStream)\n const [shapeData, setShapeData] = useState<UseShapeResult>({\n data: [...shape.valueSync.values()],\n isUpToDate: shape.isUpToDate,\n isError: shape.error !== false,\n shape,\n error: shape.error,\n })\n\n useEffect(() => {\n // Subscribe to updates.\n const unsubscribe = shape.subscribe((map) => {\n setShapeData({\n data: [...map.values()],\n isUpToDate: shape.isUpToDate,\n isError: shape.error !== false,\n shape,\n error: shape.error,\n })\n })\n\n return () => {\n unsubscribe()\n }\n }, [])\n\n return shapeData\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,SAAS,eAAe,WAAW,YAAY,gBAAgB;AACtE;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AAQP,MAAM,gBAAgB,cAAuC,IAAI;AAEjE,MAAM,cAAc,oBAAI,IAAyB;AACjD,MAAM,aAAa,oBAAI,IAAwB;AAE/C,SAAsB,aACpB,SACgB;AAAA;AAChB,UAAM,cAAc,eAAe,OAAO;AAC1C,UAAM,QAAQ,SAAS,WAAW;AAClC,UAAM,MAAM;AACZ,WAAO;AAAA,EACT;AAAA;AAEO,SAAS,kBAAkB,SAAqC;AACrE,QAAM,WAAW,KAAK;AAAA,IACpB,QAAQ;AAAA,IACR,OAAO,KAAK,QAAQ,KAAK,EAAE,KAAK;AAAA,EAClC;AAEA,QAA6C,cAArC,QAlCV,IAkC+C,IAA3B,mCAA2B,IAA3B,CAAV;AACR,QAAM,aAAa,KAAK;AAAA,IACtB;AAAA,IACA,OAAO,KAAK,OAAO,EAAE,KAAK;AAAA,EAC5B;AACA,QAAM,YAAY,WAAW;AAE7B,SAAO;AACT;AAEO,SAAS,eAAe,SAA0C;AACvE,QAAM,YAAY,kBAAkB,OAAO;AAG3C,MAAI,YAAY,IAAI,SAAS,GAAG;AAE9B,WAAO,YAAY,IAAI,SAAS;AAAA,EAClC,OAAO;AACL,UAAM,iBAAiB,IAAI,YAAY,OAAO;AAE9C,gBAAY,IAAI,WAAW,cAAc;AAGzC,WAAO;AAAA,EACT;AACF;AAEO,SAAS,SAAS,aAAiC;AAExD,MAAI,WAAW,IAAI,WAAW,GAAG;AAE/B,WAAO,WAAW,IAAI,WAAW;AAAA,EACnC,OAAO;AACL,UAAM,WAAW,IAAI,MAAM,WAAW;AAEtC,eAAW,IAAI,aAAa,QAAQ;AAGpC,WAAO;AAAA,EACT;AACF;AAOO,SAAS,eAAe,EAAE,SAAS,GAAoC;AAE5E,SACE,oCAAC,cAAc,UAAd,EAAuB,OAAO,EAAE,UAAU,eAAe,KACvD,QACH;AAEJ;AAEO,SAAS,kBAAkB;AAChC,QAAM,UAAU,WAAW,aAAa;AACxC,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AACA,SAAO;AACT;AAqBO,SAAS,SAAS,SAA6C;AACpE,QAAM,EAAE,UAAAA,WAAU,gBAAAC,gBAAe,IAAI,gBAAgB;AACrD,QAAM,cAAcA,gBAAe,OAAO;AAC1C,QAAM,QAAQD,UAAS,WAAW;AAClC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAyB;AAAA,IACzD,MAAM,CAAC,GAAG,MAAM,UAAU,OAAO,CAAC;AAAA,IAClC,YAAY,MAAM;AAAA,IAClB,SAAS,MAAM,UAAU;AAAA,IACzB;AAAA,IACA,OAAO,MAAM;AAAA,EACf,CAAC;AAED,YAAU,MAAM;AAEd,UAAM,cAAc,MAAM,UAAU,CAAC,QAAQ;AAC3C,mBAAa;AAAA,QACX,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC;AAAA,QACtB,YAAY,MAAM;AAAA,QAClB,SAAS,MAAM,UAAU;AAAA,QACzB;AAAA,QACA,OAAO,MAAM;AAAA,MACf,CAAC;AAAA,IACH,CAAC;AAED,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,SAAO;AACT;","names":["getShape","getShapeStream"]}
1
+ {"version":3,"sources":["../src/react-hooks.tsx"],"sourcesContent":["import {\n JsonSerializable,\n Shape,\n ShapeStream,\n ShapeStreamOptions,\n} from '@electric-sql/next'\nimport React, { createContext, useCallback, useContext, useRef } from 'react'\nimport { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector'\n\ninterface ShapeContextType {\n getShape: (shapeStream: ShapeStream) => Shape\n getShapeStream: (options: ShapeStreamOptions) => ShapeStream\n}\n\n// Create a Context\nconst ShapesContext = createContext<ShapeContextType | null>(null)\n\nconst streamCache = new Map<string, ShapeStream>()\nconst shapeCache = new Map<ShapeStream, Shape>()\n\nexport async function preloadShape(\n options: ShapeStreamOptions\n): Promise<Shape> {\n const shapeStream = getShapeStream(options)\n const shape = getShape(shapeStream)\n await shape.value\n return shape\n}\n\nexport function sortedOptionsHash(options: ShapeStreamOptions): string {\n const shapeDef = JSON.stringify(\n options.shape,\n Object.keys(options.shape).sort()\n )\n // eslint-disable-next-line\n const { shape, ...optionsWithoutShapeDef } = options\n const allOptions = JSON.stringify(\n optionsWithoutShapeDef,\n Object.keys(options).sort()\n )\n const shapeHash = shapeDef + allOptions\n\n return shapeHash\n}\n\nexport function getShapeStream(options: ShapeStreamOptions): ShapeStream {\n const shapeHash = sortedOptionsHash(options)\n\n // If the stream is already cached, return\n if (streamCache.has(shapeHash)) {\n // Return the ShapeStream\n return streamCache.get(shapeHash)!\n } else {\n const newShapeStream = new ShapeStream(options)\n\n streamCache.set(shapeHash, newShapeStream)\n\n // Return the created shape\n return newShapeStream\n }\n}\n\nexport function getShape(shapeStream: ShapeStream): Shape {\n // If the stream is already cached, return\n if (shapeCache.has(shapeStream)) {\n // Return the ShapeStream\n return shapeCache.get(shapeStream)!\n } else {\n const newShape = new Shape(shapeStream)\n\n shapeCache.set(shapeStream, newShape)\n\n // Return the created shape\n return newShape\n }\n}\n\ninterface ShapeProviderProps {\n children: React.ReactNode\n}\n\n// Shapes Provider Component\nexport function ShapesProvider({ children }: ShapeProviderProps): JSX.Element {\n // Provide the context value\n return (\n <ShapesContext.Provider value={{ getShape, getShapeStream }}>\n {children}\n </ShapesContext.Provider>\n )\n}\n\nexport function useShapeContext() {\n const context = useContext(ShapesContext)\n if (!context) {\n throw new Error(`useShapeContext must be used within a ShapeProvider`)\n }\n return context\n}\n\ninterface UseShapeResult {\n /**\n * The array of rows that make up the Shape.\n * @type {{ [key: string]: JsonSerializable }[]}\n */\n data: { [key: string]: JsonSerializable }[]\n /**\n * The Shape instance used by this useShape\n * @type(Shape)\n */\n shape: Shape\n error: Shape[`error`]\n isError: boolean\n /**\n * Has the ShapeStream caught up with the replication log from Postgres.\n */\n isUpToDate: boolean\n}\n\nfunction shapeSubscribe(shape: Shape, callback: () => void) {\n const unsubscribe = shape.subscribe(callback)\n return () => {\n unsubscribe()\n }\n}\n\nfunction parseShapeData(shape: Shape): UseShapeResult {\n return {\n data: [...shape.valueSync.values()],\n isUpToDate: shape.isUpToDate,\n isError: shape.error !== false,\n shape,\n error: shape.error,\n }\n}\n\nconst identity = (arg: unknown) => arg\n\ninterface UseShapeOptions<Selection> extends ShapeStreamOptions {\n selector?: (value: UseShapeResult) => Selection\n}\n\nexport function useShape<Selection = UseShapeResult>({\n selector = identity as never,\n ...options\n}: UseShapeOptions<Selection>): Selection {\n const { getShape, getShapeStream } = useShapeContext()\n const shapeStream = getShapeStream(options as ShapeStreamOptions)\n const shape = getShape(shapeStream)\n\n const latestShapeData = useRef(parseShapeData(shape))\n const getSnapshot = React.useCallback(() => latestShapeData.current, [])\n const shapeData = useSyncExternalStoreWithSelector(\n useCallback(\n (onStoreChange) =>\n shapeSubscribe(shape, () => {\n latestShapeData.current = parseShapeData(shape)\n onStoreChange()\n }),\n [shape]\n ),\n getSnapshot,\n getSnapshot,\n selector\n )\n\n return shapeData\n}\n"],"mappings":"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","names":["getShape","getShapeStream"]}
@@ -18,8 +18,9 @@ var __rest = (this && this.__rest) || function (s, e) {
18
18
  }
19
19
  return t;
20
20
  };
21
- import React, { createContext, useEffect, useContext, useState } from 'react';
22
21
  import { Shape, ShapeStream, } from '@electric-sql/next';
22
+ import React, { createContext, useCallback, useContext, useRef } from 'react';
23
+ import { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector';
23
24
  // Create a Context
24
25
  const ShapesContext = createContext(null);
25
26
  const streamCache = new Map();
@@ -81,31 +82,32 @@ export function useShapeContext() {
81
82
  }
82
83
  return context;
83
84
  }
84
- export function useShape(options) {
85
- const { getShape, getShapeStream } = useShapeContext();
86
- const shapeStream = getShapeStream(options);
87
- const shape = getShape(shapeStream);
88
- const [shapeData, setShapeData] = useState({
85
+ function shapeSubscribe(shape, callback) {
86
+ const unsubscribe = shape.subscribe(callback);
87
+ return () => {
88
+ unsubscribe();
89
+ };
90
+ }
91
+ function parseShapeData(shape) {
92
+ return {
89
93
  data: [...shape.valueSync.values()],
90
94
  isUpToDate: shape.isUpToDate,
91
95
  isError: shape.error !== false,
92
96
  shape,
93
97
  error: shape.error,
94
- });
95
- useEffect(() => {
96
- // Subscribe to updates.
97
- const unsubscribe = shape.subscribe((map) => {
98
- setShapeData({
99
- data: [...map.values()],
100
- isUpToDate: shape.isUpToDate,
101
- isError: shape.error !== false,
102
- shape,
103
- error: shape.error,
104
- });
105
- });
106
- return () => {
107
- unsubscribe();
108
- };
109
- }, []);
98
+ };
99
+ }
100
+ const identity = (arg) => arg;
101
+ export function useShape(_a) {
102
+ var { selector = identity } = _a, options = __rest(_a, ["selector"]);
103
+ const { getShape, getShapeStream } = useShapeContext();
104
+ const shapeStream = getShapeStream(options);
105
+ const shape = getShape(shapeStream);
106
+ const latestShapeData = useRef(parseShapeData(shape));
107
+ const getSnapshot = React.useCallback(() => latestShapeData.current, []);
108
+ const shapeData = useSyncExternalStoreWithSelector(useCallback((onStoreChange) => shapeSubscribe(shape, () => {
109
+ latestShapeData.current = parseShapeData(shape);
110
+ onStoreChange();
111
+ }), [shape]), getSnapshot, getSnapshot, selector);
110
112
  return shapeData;
111
113
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@electric-sql/react",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "React hooks for ElectricSQL",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -18,12 +18,14 @@
18
18
  },
19
19
  "homepage": "https://next.electric-sql.com",
20
20
  "dependencies": {
21
- "@electric-sql/next": "0.0.5"
21
+ "use-sync-external-store": "^1.2.2",
22
+ "@electric-sql/next": "0.0.7"
22
23
  },
23
24
  "devDependencies": {
24
25
  "@testing-library/react": "^16.0.0",
25
26
  "@types/pg": "^8.11.6",
26
27
  "@types/react": "^18.3.3",
28
+ "@types/use-sync-external-store": "^0.0.6",
27
29
  "@types/uuid": "^10.0.0",
28
30
  "@typescript-eslint/eslint-plugin": "^7.14.1",
29
31
  "@typescript-eslint/parser": "^7.14.1",