@instantdb/react 0.22.89-experimental.drewh-ssr.20285043124.1 → 0.22.89-experimental.sync-table-fixes.20282627123.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.
Files changed (40) hide show
  1. package/dist/commonjs/index.d.ts +2 -2
  2. package/dist/commonjs/index.d.ts.map +1 -1
  3. package/dist/commonjs/index.js +1 -2
  4. package/dist/commonjs/index.js.map +1 -1
  5. package/dist/esm/index.d.ts +2 -2
  6. package/dist/esm/index.d.ts.map +1 -1
  7. package/dist/esm/index.js +2 -2
  8. package/dist/esm/index.js.map +1 -1
  9. package/dist/standalone/index.js +1962 -2079
  10. package/dist/standalone/index.umd.cjs +14 -14
  11. package/package.json +6 -18
  12. package/src/index.ts +0 -2
  13. package/tsconfig.json +0 -1
  14. package/dist/commonjs/next-ssr/HydrationStreamProvider.d.ts +0 -66
  15. package/dist/commonjs/next-ssr/HydrationStreamProvider.d.ts.map +0 -1
  16. package/dist/commonjs/next-ssr/HydrationStreamProvider.js +0 -135
  17. package/dist/commonjs/next-ssr/HydrationStreamProvider.js.map +0 -1
  18. package/dist/commonjs/next-ssr/htmlescape.d.ts +0 -3
  19. package/dist/commonjs/next-ssr/htmlescape.d.ts.map +0 -1
  20. package/dist/commonjs/next-ssr/htmlescape.js +0 -25
  21. package/dist/commonjs/next-ssr/htmlescape.js.map +0 -1
  22. package/dist/commonjs/next-ssr/index.d.ts +0 -50
  23. package/dist/commonjs/next-ssr/index.d.ts.map +0 -1
  24. package/dist/commonjs/next-ssr/index.js +0 -158
  25. package/dist/commonjs/next-ssr/index.js.map +0 -1
  26. package/dist/esm/next-ssr/HydrationStreamProvider.d.ts +0 -66
  27. package/dist/esm/next-ssr/HydrationStreamProvider.d.ts.map +0 -1
  28. package/dist/esm/next-ssr/HydrationStreamProvider.js +0 -98
  29. package/dist/esm/next-ssr/HydrationStreamProvider.js.map +0 -1
  30. package/dist/esm/next-ssr/htmlescape.d.ts +0 -3
  31. package/dist/esm/next-ssr/htmlescape.d.ts.map +0 -1
  32. package/dist/esm/next-ssr/htmlescape.js +0 -21
  33. package/dist/esm/next-ssr/htmlescape.js.map +0 -1
  34. package/dist/esm/next-ssr/index.d.ts +0 -50
  35. package/dist/esm/next-ssr/index.d.ts.map +0 -1
  36. package/dist/esm/next-ssr/index.js +0 -148
  37. package/dist/esm/next-ssr/index.js.map +0 -1
  38. package/src/next-ssr/HydrationStreamProvider.tsx +0 -193
  39. package/src/next-ssr/htmlescape.ts +0 -24
  40. package/src/next-ssr/index.tsx +0 -264
@@ -1,66 +0,0 @@
1
- export declare const isServer: boolean;
2
- import * as React from 'react';
3
- interface DataTransformer {
4
- serialize: (object: any) => any;
5
- deserialize: (object: any) => any;
6
- }
7
- interface HydrationStreamContext<TShape> {
8
- id: string;
9
- stream: {
10
- /**
11
- * **Server method**
12
- * Push a new entry to the stream
13
- * Will be ignored on the client
14
- */
15
- push: (...shape: Array<TShape>) => void;
16
- };
17
- }
18
- export interface HydrationStreamProviderProps<TShape> {
19
- children: React.ReactNode;
20
- /**
21
- * Optional transformer to serialize/deserialize the data
22
- * Example devalue, superjson et al
23
- */
24
- transformer?: DataTransformer;
25
- /**
26
- * **Client method**
27
- * Called in the browser when new entries are received
28
- */
29
- onEntries: (entries: Array<TShape>) => void;
30
- /**
31
- * **Server method**
32
- * onFlush is called on the server when the cache is flushed
33
- */
34
- onFlush?: () => Array<TShape>;
35
- /**
36
- * A nonce that'll allow the inline script to be executed when Content Security Policy is enforced
37
- */
38
- nonce?: string;
39
- }
40
- export declare function createHydrationStreamProvider<TShape>(): {
41
- Provider: (props: {
42
- children: React.ReactNode;
43
- /**
44
- * Optional transformer to serialize/deserialize the data
45
- * Example devalue, superjson et al
46
- */
47
- transformer?: DataTransformer;
48
- /**
49
- * **Client method**
50
- * Called in the browser when new entries are received
51
- */
52
- onEntries: (entries: Array<TShape>) => void;
53
- /**
54
- * **Server method**
55
- * onFlush is called on the server when the cache is flushed
56
- */
57
- onFlush?: () => Array<TShape>;
58
- /**
59
- * A nonce that'll allow the inline script to be executed when Content Security Policy is enforced
60
- */
61
- nonce?: string;
62
- }) => import("react/jsx-runtime").JSX.Element;
63
- context: React.Context<HydrationStreamContext<TShape>>;
64
- };
65
- export {};
66
- //# sourceMappingURL=HydrationStreamProvider.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"HydrationStreamProvider.d.ts","sourceRoot":"","sources":["../../../src/next-ssr/HydrationStreamProvider.tsx"],"names":[],"mappings":"AACA,eAAO,MAAM,QAAQ,SAAwD,CAAC;AAI9E,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,UAAU,eAAe;IACvB,SAAS,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;IAChC,WAAW,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAC;CACnC;AAWD,UAAU,sBAAsB,CAAC,MAAM;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE;QACN;;;;WAIG;QACH,IAAI,EAAE,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;KACzC,CAAC;CACH;AAED,MAAM,WAAW,4BAA4B,CAAC,MAAM;IAClD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B;;;OAGG;IACH,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B;;;OAGG;IACH,SAAS,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IAC5C;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,6BAA6B,CAAC,MAAM;sBAaD;QAC/C,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;QAC1B;;;WAGG;QACH,WAAW,CAAC,EAAE,eAAe,CAAC;QAC9B;;;WAGG;QACH,SAAS,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;QAC5C;;;WAGG;QACH,OAAO,CAAC,EAAE,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;QAC9B;;WAEG;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB;;EAmGF"}
@@ -1,98 +0,0 @@
1
- 'use client';
2
- import { jsx as _jsx } from "react/jsx-runtime";
3
- export const isServer = typeof window === 'undefined' || 'Deno' in globalThis;
4
- import { useServerInsertedHTML } from 'next/navigation.js';
5
- import * as React from 'react';
6
- import { htmlEscapeJsonString } from './htmlescape.js';
7
- const serializedSymbol = Symbol('serialized');
8
- export function createHydrationStreamProvider() {
9
- const context = React.createContext(null);
10
- /**
11
-
12
- * 1. (Happens on server): `useServerInsertedHTML()` is called **on the server** whenever a `Suspense`-boundary completes
13
- * - This means that we might have some new entries in the cache that needs to be flushed
14
- * - We pass these to the client by inserting a `<script>`-tag where we do `window[id].push(serializedVersionOfCache)`
15
- * 2. (Happens in browser) In `useEffect()`:
16
- * - We check if `window[id]` is set to an array and call `push()` on all the entries which will call `onEntries()` with the new entries
17
- * - We replace `window[id]` with a `push()`-method that will be called whenever new entries are received
18
- **/
19
- function UseClientHydrationStreamProvider(props) {
20
- var _a, _b;
21
- // unique id for the cache provider
22
- const id = `__RQ${React.useId()}`;
23
- const idJSON = htmlEscapeJsonString(JSON.stringify(id));
24
- const [transformer] = React.useState(() => {
25
- var _a;
26
- return ((_a = props.transformer) !== null && _a !== void 0 ? _a : {
27
- // noop
28
- serialize: (obj) => obj,
29
- deserialize: (obj) => obj,
30
- });
31
- });
32
- // <server stuff>
33
- const [stream] = React.useState(() => {
34
- if (!isServer) {
35
- return {
36
- push() {
37
- // no-op on the client
38
- },
39
- };
40
- }
41
- return [];
42
- });
43
- const count = React.useRef(0);
44
- useServerInsertedHTML(() => {
45
- var _a, _b;
46
- // This only happens on the server
47
- stream.push(...((_b = (_a = props.onFlush) === null || _a === void 0 ? void 0 : _a.call(props)) !== null && _b !== void 0 ? _b : []));
48
- if (!stream.length) {
49
- return null;
50
- }
51
- // console.log(`pushing ${stream.length} entries`)
52
- const serializedCacheArgs = stream
53
- .map((entry) => transformer.serialize(entry))
54
- .map((entry) => JSON.stringify(entry))
55
- .join(',');
56
- // Flush stream
57
- // eslint-disable-next-line react-hooks/immutability
58
- stream.length = 0;
59
- const html = [
60
- `window[${idJSON}] = window[${idJSON}] || [];`,
61
- `window[${idJSON}].push(${htmlEscapeJsonString(serializedCacheArgs)});`,
62
- ];
63
- return (_jsx("script", { nonce: props.nonce, dangerouslySetInnerHTML: {
64
- __html: html.join(''),
65
- } }, count.current++));
66
- });
67
- // </server stuff>
68
- // <client stuff>
69
- // Setup and run the onEntries handler on the client only, but do it during
70
- // the initial render so children have access to the data immediately
71
- // This is important to avoid the client suspending during the initial render
72
- // if the data has not yet been hydrated.
73
- if (!isServer) {
74
- const win = window;
75
- if (!((_a = win[id]) === null || _a === void 0 ? void 0 : _a.initialized)) {
76
- // Client: consume cache:
77
- const onEntries = (...serializedEntries) => {
78
- const entries = serializedEntries.map((serialized) => transformer.deserialize(serialized));
79
- props.onEntries(entries);
80
- };
81
- const winStream = (_b = win[id]) !== null && _b !== void 0 ? _b : [];
82
- onEntries(...winStream);
83
- // eslint-disable-next-line react-hooks/immutability
84
- win[id] = {
85
- initialized: true,
86
- push: onEntries,
87
- };
88
- }
89
- }
90
- // </client stuff>
91
- return (_jsx(context.Provider, { value: { stream, id }, children: props.children }));
92
- }
93
- return {
94
- Provider: UseClientHydrationStreamProvider,
95
- context,
96
- };
97
- }
98
- //# sourceMappingURL=HydrationStreamProvider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"HydrationStreamProvider.js","sourceRoot":"","sources":["../../../src/next-ssr/HydrationStreamProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nexport const isServer = typeof window === 'undefined' || 'Deno' in globalThis;\n\nimport { useServerInsertedHTML } from 'next/navigation.js';\n\nimport * as React from 'react';\nimport { htmlEscapeJsonString } from './htmlescape.js';\n\nconst serializedSymbol = Symbol('serialized');\n\ninterface DataTransformer {\n serialize: (object: any) => any;\n deserialize: (object: any) => any;\n}\n\ntype Serialized<TData> = unknown & {\n [serializedSymbol]: TData;\n};\n\ninterface TypedDataTransformer<TData> {\n serialize: (obj: TData) => Serialized<TData>;\n deserialize: (obj: Serialized<TData>) => TData;\n}\n\ninterface HydrationStreamContext<TShape> {\n id: string;\n stream: {\n /**\n * **Server method**\n * Push a new entry to the stream\n * Will be ignored on the client\n */\n push: (...shape: Array<TShape>) => void;\n };\n}\n\nexport interface HydrationStreamProviderProps<TShape> {\n children: React.ReactNode;\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer;\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void;\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>;\n /**\n * A nonce that'll allow the inline script to be executed when Content Security Policy is enforced\n */\n nonce?: string;\n}\n\nexport function createHydrationStreamProvider<TShape>() {\n const context = React.createContext<HydrationStreamContext<TShape>>(\n null as any,\n );\n /**\n\n * 1. (Happens on server): `useServerInsertedHTML()` is called **on the server** whenever a `Suspense`-boundary completes\n * - This means that we might have some new entries in the cache that needs to be flushed\n * - We pass these to the client by inserting a `<script>`-tag where we do `window[id].push(serializedVersionOfCache)`\n * 2. (Happens in browser) In `useEffect()`:\n * - We check if `window[id]` is set to an array and call `push()` on all the entries which will call `onEntries()` with the new entries\n * - We replace `window[id]` with a `push()`-method that will be called whenever new entries are received\n **/\n function UseClientHydrationStreamProvider(props: {\n children: React.ReactNode;\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer;\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void;\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>;\n /**\n * A nonce that'll allow the inline script to be executed when Content Security Policy is enforced\n */\n nonce?: string;\n }) {\n // unique id for the cache provider\n const id = `__RQ${React.useId()}`;\n const idJSON = htmlEscapeJsonString(JSON.stringify(id));\n\n const [transformer] = React.useState(\n () =>\n (props.transformer ?? {\n // noop\n serialize: (obj: any) => obj,\n deserialize: (obj: any) => obj,\n }) as unknown as TypedDataTransformer<TShape>,\n );\n\n // <server stuff>\n const [stream] = React.useState<Array<TShape>>(() => {\n if (!isServer) {\n return {\n push() {\n // no-op on the client\n },\n } as unknown as Array<TShape>;\n }\n return [];\n });\n const count = React.useRef(0);\n useServerInsertedHTML(() => {\n // This only happens on the server\n stream.push(...(props.onFlush?.() ?? []));\n\n if (!stream.length) {\n return null;\n }\n // console.log(`pushing ${stream.length} entries`)\n const serializedCacheArgs = stream\n .map((entry) => transformer.serialize(entry))\n .map((entry) => JSON.stringify(entry))\n .join(',');\n\n // Flush stream\n // eslint-disable-next-line react-hooks/immutability\n stream.length = 0;\n\n const html: Array<string> = [\n `window[${idJSON}] = window[${idJSON}] || [];`,\n `window[${idJSON}].push(${htmlEscapeJsonString(serializedCacheArgs)});`,\n ];\n return (\n <script\n key={count.current++}\n nonce={props.nonce}\n dangerouslySetInnerHTML={{\n __html: html.join(''),\n }}\n />\n );\n });\n // </server stuff>\n\n // <client stuff>\n // Setup and run the onEntries handler on the client only, but do it during\n // the initial render so children have access to the data immediately\n // This is important to avoid the client suspending during the initial render\n // if the data has not yet been hydrated.\n if (!isServer) {\n const win = window as any;\n if (!win[id]?.initialized) {\n // Client: consume cache:\n const onEntries = (...serializedEntries: Array<Serialized<TShape>>) => {\n const entries = serializedEntries.map((serialized) =>\n transformer.deserialize(serialized),\n );\n props.onEntries(entries);\n };\n\n const winStream: Array<Serialized<TShape>> = win[id] ?? [];\n\n onEntries(...winStream);\n\n // eslint-disable-next-line react-hooks/immutability\n win[id] = {\n initialized: true,\n push: onEntries,\n };\n }\n }\n // </client stuff>\n\n return (\n <context.Provider value={{ stream, id }}>\n {props.children}\n </context.Provider>\n );\n }\n\n return {\n Provider: UseClientHydrationStreamProvider,\n context,\n };\n}\n"]}
@@ -1,3 +0,0 @@
1
- export declare const ESCAPE_REGEX: RegExp;
2
- export declare function htmlEscapeJsonString(str: string): string;
3
- //# sourceMappingURL=htmlescape.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"htmlescape.d.ts","sourceRoot":"","sources":["../../../src/next-ssr/htmlescape.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,YAAY,QAAuB,CAAC;AAEjD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAExD"}
@@ -1,21 +0,0 @@
1
- // --------------------------------------------------------------------------------
2
- //
3
- // copied from
4
- // https://github.com/vercel/next.js/blob/6bc07792a4462a4bf921a72ab30dc4ab2c4e1bda/packages/next/src/server/htmlescape.ts
5
- // License: https://github.com/vercel/next.js/blob/6bc07792a4462a4bf921a72ab30dc4ab2c4e1bda/packages/next/license.md
6
- //
7
- // --------------------------------------------------------------------------------
8
- // This utility is based on https://github.com/zertosh/htmlescape
9
- // License: https://github.com/zertosh/htmlescape/blob/0527ca7156a524d256101bb310a9f970f63078ad/LICENSE
10
- const ESCAPE_LOOKUP = {
11
- '&': '\\u0026',
12
- '>': '\\u003e',
13
- '<': '\\u003c',
14
- '\u2028': '\\u2028',
15
- '\u2029': '\\u2029',
16
- };
17
- export const ESCAPE_REGEX = /[&><\u2028\u2029]/g;
18
- export function htmlEscapeJsonString(str) {
19
- return str.replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]);
20
- }
21
- //# sourceMappingURL=htmlescape.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"htmlescape.js","sourceRoot":"","sources":["../../../src/next-ssr/htmlescape.ts"],"names":[],"mappings":"AAAA,mFAAmF;AACnF,EAAE;AACF,cAAc;AACd,yHAAyH;AACzH,oHAAoH;AACpH,EAAE;AACF,mFAAmF;AAEnF,iEAAiE;AACjE,uGAAuG;AAEvG,MAAM,aAAa,GAA2B;IAC5C,GAAG,EAAE,SAAS;IACd,GAAG,EAAE,SAAS;IACd,GAAG,EAAE,SAAS;IACd,QAAQ,EAAE,SAAS;IACnB,QAAQ,EAAE,SAAS;CACpB,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,oBAAoB,CAAC;AAEjD,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC9C,OAAO,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAE,CAAC,CAAC;AACrE,CAAC","sourcesContent":["// --------------------------------------------------------------------------------\n//\n// copied from\n// https://github.com/vercel/next.js/blob/6bc07792a4462a4bf921a72ab30dc4ab2c4e1bda/packages/next/src/server/htmlescape.ts\n// License: https://github.com/vercel/next.js/blob/6bc07792a4462a4bf921a72ab30dc4ab2c4e1bda/packages/next/license.md\n//\n// --------------------------------------------------------------------------------\n\n// This utility is based on https://github.com/zertosh/htmlescape\n// License: https://github.com/zertosh/htmlescape/blob/0527ca7156a524d256101bb310a9f970f63078ad/LICENSE\n\nconst ESCAPE_LOOKUP: Record<string, string> = {\n '&': '\\\\u0026',\n '>': '\\\\u003e',\n '<': '\\\\u003c',\n '\\u2028': '\\\\u2028',\n '\\u2029': '\\\\u2029',\n};\n\nexport const ESCAPE_REGEX = /[&><\\u2028\\u2029]/g;\n\nexport function htmlEscapeJsonString(str: string): string {\n return str.replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]!);\n}\n"]}
@@ -1,50 +0,0 @@
1
- import { AuthState, InstantConfig, InstantSchemaDef, InstantUnknownSchema, InstaQLResponse, PageInfoResponse, RuleParams, User, ValidQuery } from '@instantdb/core';
2
- import InstantReactWebDatabase from '../InstantReactWebDatabase.ts';
3
- type InstantSuspenseProviderProps<Schema extends InstantSchemaDef<any, any, any>> = {
4
- nonce?: string;
5
- children: React.ReactNode;
6
- db?: InstantReactWebDatabase<Schema, any>;
7
- config?: Omit<InstantConfig<any, any>, 'schema'> & {
8
- schema: string;
9
- };
10
- user?: User | null;
11
- };
12
- export declare const createUseSuspenseQuery: <Schema extends InstantSchemaDef<any, any, any>, UseDates extends boolean>(_db: InstantReactWebDatabase<Schema, UseDates>) => (<Q extends ValidQuery<Q, Schema>>(q: Q, opts?: {
13
- ruleParams: RuleParams;
14
- }) => {
15
- data: InstaQLResponse<Schema, Q, NonNullable<UseDates>>;
16
- pageInfo?: PageInfoResponse<Q>;
17
- });
18
- export declare const InstantSuspenseProvider: (props: InstantSuspenseProviderProps<any>) => import("react/jsx-runtime").JSX.Element;
19
- /**
20
- *
21
- * The first step: init your application!
22
- *
23
- * Visit https://instantdb.com/dash to get your `appId` :)
24
- *
25
- * @example
26
- * import { init } from "@instantdb/react"
27
- *
28
- * const db = init({ appId: "my-app-id" })
29
- *
30
- * // You can also provide a schema for type safety and editor autocomplete!
31
- *
32
- * import { init } from "@instantdb/react"
33
- * import schema from ""../instant.schema.ts";
34
- *
35
- * const db = init({ appId: "my-app-id", schema })
36
- *
37
- * // To learn more: https://instantdb.com/docs/modeling-data
38
- */
39
- export declare function init<Schema extends InstantSchemaDef<any, any, any> = InstantUnknownSchema, UseDates extends boolean = false>(config: InstantConfig<Schema, UseDates>): InstantNextDatabase<Schema, UseDates>;
40
- export declare class InstantNextDatabase<Schema extends InstantSchemaDef<any, any, any>, UseDates extends boolean> extends InstantReactWebDatabase<Schema, UseDates> {
41
- useSuspenseQuery: <Q extends ValidQuery<Q, Schema>>(q: Q, opts?: {
42
- ruleParams: RuleParams;
43
- }) => {
44
- data: InstaQLResponse<Schema, Q, NonNullable<UseDates>>;
45
- pageInfo?: PageInfoResponse<Q>;
46
- };
47
- useAuth: () => AuthState;
48
- }
49
- export {};
50
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/next-ssr/index.tsx"],"names":[],"mappings":"AACA,OAAO,EACL,SAAS,EAET,aAAa,EACb,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,IAAI,EACJ,UAAU,EACX,MAAM,iBAAiB,CAAC;AAQzB,OAAO,uBAAuB,MAAM,+BAA+B,CAAC;AAGpE,KAAK,4BAA4B,CAC/B,MAAM,SAAS,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,IAC5C;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,EAAE,CAAC,EAAE,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1C,MAAM,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,GAAG;QACjD,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACpB,CAAC;AAcF,eAAO,MAAM,sBAAsB,GACjC,MAAM,SAAS,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC9C,QAAQ,SAAS,OAAO,EAExB,KAAK,uBAAuB,CAAC,MAAM,EAAE,QAAQ,CAAC,KAC7C,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,EAClC,CAAC,EAAE,CAAC,EACJ,IAAI,CAAC,EAAE;IACL,UAAU,EAAE,UAAU,CAAC;CACxB,KACE;IACH,IAAI,EAAE,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxD,QAAQ,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;CAChC,CAUA,CAAC;AAMF,eAAO,MAAM,uBAAuB,GAClC,OAAO,4BAA4B,CAAC,GAAG,CAAC,4CA8GzC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,IAAI,CAClB,MAAM,SAAS,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,oBAAoB,EACrE,QAAQ,SAAS,OAAO,GAAG,KAAK,EAEhC,MAAM,EAAE,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,GACtC,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAIvC;AAED,qBAAa,mBAAmB,CAC9B,MAAM,SAAS,gBAAgB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAC9C,QAAQ,SAAS,OAAO,CACxB,SAAQ,uBAAuB,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1C,gBAAgB,GAAI,CAAC,SAAS,UAAU,CAAC,CAAC,EAAE,MAAM,CAAC,EACxD,GAAG,CAAC,EACJ,OAAO;QACL,UAAU,EAAE,UAAU,CAAC;KACxB,KACA;QACD,IAAI,EAAE,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;QACxD,QAAQ,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;KAChC,CAQC;IAEF,OAAO,QAAO,SAAS,CAoBrB;CACH"}
@@ -1,148 +0,0 @@
1
- 'use client';
2
- import { jsx as _jsx } from "react/jsx-runtime";
3
- import { FrameworkClient, } from '@instantdb/core';
4
- import { createContext, useContext, useRef, useState } from 'react';
5
- import { createHydrationStreamProvider, isServer, } from "./HydrationStreamProvider.js";
6
- import version from "../version.js";
7
- import InstantReactWebDatabase from "../InstantReactWebDatabase.js";
8
- const stream = createHydrationStreamProvider();
9
- const SuspsenseQueryContext = createContext(null);
10
- // Creates a typed useSuspense hook
11
- export const createUseSuspenseQuery = (_db) => {
12
- return (q, opts) => {
13
- const ctx = useContext(SuspsenseQueryContext);
14
- if (!ctx) {
15
- throw new Error('useSuspenseQuery must be used within a SuspenseQueryProvider');
16
- }
17
- return ctx.useSuspenseQuery(q, opts);
18
- };
19
- };
20
- export const InstantSuspenseProvider = (props) => {
21
- var _a;
22
- const clientRef = useRef(null);
23
- if (!props.db) {
24
- throw new Error('Must provide either a db or config to InstantSuspenseProvider');
25
- }
26
- const db = useRef(props.db);
27
- const [trackedKeys] = useState(() => new Set());
28
- if (!clientRef.current) {
29
- if (props.user && !props.user.refresh_token) {
30
- throw new Error('User must have a refresh_token field. Recieved: ' +
31
- JSON.stringify(props.user, null, 2));
32
- }
33
- clientRef.current = new FrameworkClient({
34
- token: (_a = props.user) === null || _a === void 0 ? void 0 : _a.refresh_token,
35
- db: db.current.core,
36
- });
37
- }
38
- if (isServer) {
39
- clientRef.current.subscribe((result) => {
40
- const { queryHash } = result;
41
- trackedKeys.add(queryHash);
42
- });
43
- }
44
- const useSuspenseQuery = (query, opts) => {
45
- const nonSuspenseResult = db.current.useQuery(query, Object.assign({}, opts));
46
- if (nonSuspenseResult.data) {
47
- return {
48
- data: nonSuspenseResult.data,
49
- pageInfo: nonSuspenseResult.pageInfo,
50
- };
51
- }
52
- // should never happen (typeguard)
53
- if (!clientRef.current) {
54
- throw new Error('Client ref not set up');
55
- }
56
- let entry = clientRef.current.getExistingResultForQuery(query, {
57
- ruleParams: opts === null || opts === void 0 ? void 0 : opts.ruleParams,
58
- });
59
- if (!entry) {
60
- entry = clientRef.current.query(query, opts);
61
- }
62
- if (entry.status === 'pending') {
63
- throw entry.promise;
64
- }
65
- if (entry.status === 'error') {
66
- throw entry.error;
67
- }
68
- if (entry.status === 'success') {
69
- const data = entry.data;
70
- const result = clientRef.current.completeIsomorphic(query, data.triples, data.attrs, data.pageInfo);
71
- return result;
72
- }
73
- };
74
- return (_jsx(SuspsenseQueryContext.Provider, { value: { useSuspenseQuery, ssrUser: props.user }, children: _jsx(stream.Provider, { nonce: props.nonce, onFlush: () => {
75
- const toSend = [];
76
- for (const [key, value] of clientRef.current.resultMap.entries()) {
77
- if (trackedKeys.has(key) && value.status === 'success') {
78
- toSend.push({
79
- queryKey: key,
80
- value: value.data,
81
- });
82
- }
83
- }
84
- trackedKeys.clear();
85
- return toSend;
86
- }, onEntries: (entries) => {
87
- entries.forEach((entry) => {
88
- clientRef.current.addQueryResult(entry.queryKey, entry.value);
89
- });
90
- }, children: props.children }) }));
91
- };
92
- /**
93
- *
94
- * The first step: init your application!
95
- *
96
- * Visit https://instantdb.com/dash to get your `appId` :)
97
- *
98
- * @example
99
- * import { init } from "@instantdb/react"
100
- *
101
- * const db = init({ appId: "my-app-id" })
102
- *
103
- * // You can also provide a schema for type safety and editor autocomplete!
104
- *
105
- * import { init } from "@instantdb/react"
106
- * import schema from ""../instant.schema.ts";
107
- *
108
- * const db = init({ appId: "my-app-id", schema })
109
- *
110
- * // To learn more: https://instantdb.com/docs/modeling-data
111
- */
112
- export function init(config) {
113
- return new InstantNextDatabase(config, {
114
- '@instantdb/react': version,
115
- });
116
- }
117
- export class InstantNextDatabase extends InstantReactWebDatabase {
118
- constructor() {
119
- super(...arguments);
120
- this.useSuspenseQuery = (q, opts) => {
121
- const ctx = useContext(SuspsenseQueryContext);
122
- if (!ctx) {
123
- throw new Error('useSuspenseQuery must be used within a SuspenseQueryProvider');
124
- }
125
- return ctx.useSuspenseQuery(q, opts);
126
- };
127
- this.useAuth = () => {
128
- const ctx = useContext(SuspsenseQueryContext);
129
- const realAuthResult = this._useAuth();
130
- if (!ctx) {
131
- return realAuthResult;
132
- }
133
- const { ssrUser } = ctx;
134
- if (ssrUser === undefined) {
135
- return realAuthResult;
136
- }
137
- if (realAuthResult.isLoading) {
138
- return {
139
- error: undefined,
140
- isLoading: false,
141
- user: ssrUser !== null && ssrUser !== void 0 ? ssrUser : undefined, // null -> undefined for the response
142
- };
143
- }
144
- return realAuthResult;
145
- };
146
- }
147
- }
148
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/next-ssr/index.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\nimport {\n AuthState,\n FrameworkClient,\n InstantConfig,\n InstantSchemaDef,\n InstantUnknownSchema,\n InstaQLResponse,\n PageInfoResponse,\n RuleParams,\n User,\n ValidQuery,\n} from '@instantdb/core';\nimport { createContext, useContext, useRef, useState } from 'react';\nimport {\n createHydrationStreamProvider,\n isServer,\n} from './HydrationStreamProvider.tsx';\nimport version from '../version.ts';\n\nimport InstantReactWebDatabase from '../InstantReactWebDatabase.ts';\nimport { InstantReactAbstractDatabase } from '@instantdb/react-common';\n\ntype InstantSuspenseProviderProps<\n Schema extends InstantSchemaDef<any, any, any>,\n> = {\n nonce?: string;\n children: React.ReactNode;\n db?: InstantReactWebDatabase<Schema, any>;\n config?: Omit<InstantConfig<any, any>, 'schema'> & {\n schema: string;\n };\n user?: User | null;\n};\n\nconst stream = createHydrationStreamProvider<any>();\n\ntype SuspenseQueryContextValue = {\n useSuspenseQuery: (query: any, opts?: SuspenseQueryOpts) => any;\n ssrUser: User | null | undefined;\n};\n\nconst SuspsenseQueryContext = createContext<SuspenseQueryContextValue | null>(\n null,\n);\n\n// Creates a typed useSuspense hook\nexport const createUseSuspenseQuery = <\n Schema extends InstantSchemaDef<any, any, any>,\n UseDates extends boolean,\n>(\n _db: InstantReactWebDatabase<Schema, UseDates>,\n): (<Q extends ValidQuery<Q, Schema>>(\n q: Q,\n opts?: {\n ruleParams: RuleParams;\n },\n) => {\n data: InstaQLResponse<Schema, Q, NonNullable<UseDates>>;\n pageInfo?: PageInfoResponse<Q>;\n}) => {\n return <Q extends ValidQuery<Q, Schema>>(q: any, opts: any) => {\n const ctx = useContext(SuspsenseQueryContext);\n if (!ctx) {\n throw new Error(\n 'useSuspenseQuery must be used within a SuspenseQueryProvider',\n );\n }\n return ctx.useSuspenseQuery(q, opts) as any;\n };\n};\n\ntype SuspenseQueryOpts = {\n ruleParams: RuleParams;\n};\n\nexport const InstantSuspenseProvider = (\n props: InstantSuspenseProviderProps<any>,\n) => {\n const clientRef = useRef<FrameworkClient | null>(null);\n\n if (!props.db) {\n throw new Error(\n 'Must provide either a db or config to InstantSuspenseProvider',\n );\n }\n\n const db = useRef<InstantReactAbstractDatabase<any, any>>(props.db);\n\n const [trackedKeys] = useState(() => new Set<string>());\n\n if (!clientRef.current) {\n if (props.user && !props.user.refresh_token) {\n throw new Error(\n 'User must have a refresh_token field. Recieved: ' +\n JSON.stringify(props.user, null, 2),\n );\n }\n clientRef.current = new FrameworkClient({\n token: props.user?.refresh_token,\n db: db.current.core,\n });\n }\n\n if (isServer) {\n clientRef.current.subscribe((result) => {\n const { queryHash } = result;\n trackedKeys.add(queryHash);\n });\n }\n\n const useSuspenseQuery = (query: any, opts: SuspenseQueryOpts) => {\n const nonSuspenseResult = db.current.useQuery(query, {\n ...opts,\n });\n\n if (nonSuspenseResult.data) {\n return {\n data: nonSuspenseResult.data,\n pageInfo: nonSuspenseResult.pageInfo,\n };\n }\n\n // should never happen (typeguard)\n if (!clientRef.current) {\n throw new Error('Client ref not set up');\n }\n\n let entry = clientRef.current.getExistingResultForQuery(query, {\n ruleParams: opts?.ruleParams,\n });\n\n if (!entry) {\n entry = clientRef.current!.query(query, opts);\n }\n\n if (entry.status === 'pending') {\n throw entry.promise;\n }\n\n if (entry.status === 'error') {\n throw entry.error;\n }\n\n if (entry.status === 'success') {\n const data = entry.data;\n const result = clientRef.current.completeIsomorphic(\n query,\n data.triples,\n data.attrs,\n data.pageInfo,\n );\n\n return result;\n }\n };\n\n return (\n <SuspsenseQueryContext.Provider\n value={{ useSuspenseQuery, ssrUser: props.user }}\n >\n <stream.Provider\n nonce={props.nonce}\n onFlush={() => {\n const toSend: { queryKey: string; value: any }[] = [];\n for (const [key, value] of clientRef.current!.resultMap.entries()) {\n if (trackedKeys.has(key) && value.status === 'success') {\n toSend.push({\n queryKey: key,\n value: value.data,\n });\n }\n }\n\n trackedKeys.clear();\n return toSend;\n }}\n onEntries={(entries) => {\n entries.forEach((entry) => {\n clientRef.current!.addQueryResult(entry.queryKey, entry.value);\n });\n }}\n >\n {props.children}\n </stream.Provider>\n </SuspsenseQueryContext.Provider>\n );\n};\n\n/**\n *\n * The first step: init your application!\n *\n * Visit https://instantdb.com/dash to get your `appId` :)\n *\n * @example\n * import { init } from \"@instantdb/react\"\n *\n * const db = init({ appId: \"my-app-id\" })\n *\n * // You can also provide a schema for type safety and editor autocomplete!\n *\n * import { init } from \"@instantdb/react\"\n * import schema from \"\"../instant.schema.ts\";\n *\n * const db = init({ appId: \"my-app-id\", schema })\n *\n * // To learn more: https://instantdb.com/docs/modeling-data\n */\nexport function init<\n Schema extends InstantSchemaDef<any, any, any> = InstantUnknownSchema,\n UseDates extends boolean = false,\n>(\n config: InstantConfig<Schema, UseDates>,\n): InstantNextDatabase<Schema, UseDates> {\n return new InstantNextDatabase<Schema, UseDates>(config, {\n '@instantdb/react': version,\n });\n}\n\nexport class InstantNextDatabase<\n Schema extends InstantSchemaDef<any, any, any>,\n UseDates extends boolean,\n> extends InstantReactWebDatabase<Schema, UseDates> {\n public useSuspenseQuery = <Q extends ValidQuery<Q, Schema>>(\n q: Q,\n opts?: {\n ruleParams: RuleParams;\n },\n ): {\n data: InstaQLResponse<Schema, Q, NonNullable<UseDates>>;\n pageInfo?: PageInfoResponse<Q>;\n } => {\n const ctx = useContext(SuspsenseQueryContext);\n if (!ctx) {\n throw new Error(\n 'useSuspenseQuery must be used within a SuspenseQueryProvider',\n );\n }\n return ctx.useSuspenseQuery(q, opts) as any;\n };\n\n useAuth = (): AuthState => {\n const ctx = useContext(SuspsenseQueryContext);\n const realAuthResult = this._useAuth();\n if (!ctx) {\n return realAuthResult;\n }\n\n const { ssrUser } = ctx;\n if (ssrUser === undefined) {\n return realAuthResult;\n }\n if (realAuthResult.isLoading) {\n return {\n error: undefined,\n isLoading: false,\n user: ssrUser ?? undefined, // null -> undefined for the response\n };\n }\n\n return realAuthResult;\n };\n}\n"]}
@@ -1,193 +0,0 @@
1
- 'use client';
2
- export const isServer = typeof window === 'undefined' || 'Deno' in globalThis;
3
-
4
- import { useServerInsertedHTML } from 'next/navigation.js';
5
-
6
- import * as React from 'react';
7
- import { htmlEscapeJsonString } from './htmlescape.js';
8
-
9
- const serializedSymbol = Symbol('serialized');
10
-
11
- interface DataTransformer {
12
- serialize: (object: any) => any;
13
- deserialize: (object: any) => any;
14
- }
15
-
16
- type Serialized<TData> = unknown & {
17
- [serializedSymbol]: TData;
18
- };
19
-
20
- interface TypedDataTransformer<TData> {
21
- serialize: (obj: TData) => Serialized<TData>;
22
- deserialize: (obj: Serialized<TData>) => TData;
23
- }
24
-
25
- interface HydrationStreamContext<TShape> {
26
- id: string;
27
- stream: {
28
- /**
29
- * **Server method**
30
- * Push a new entry to the stream
31
- * Will be ignored on the client
32
- */
33
- push: (...shape: Array<TShape>) => void;
34
- };
35
- }
36
-
37
- export interface HydrationStreamProviderProps<TShape> {
38
- children: React.ReactNode;
39
- /**
40
- * Optional transformer to serialize/deserialize the data
41
- * Example devalue, superjson et al
42
- */
43
- transformer?: DataTransformer;
44
- /**
45
- * **Client method**
46
- * Called in the browser when new entries are received
47
- */
48
- onEntries: (entries: Array<TShape>) => void;
49
- /**
50
- * **Server method**
51
- * onFlush is called on the server when the cache is flushed
52
- */
53
- onFlush?: () => Array<TShape>;
54
- /**
55
- * A nonce that'll allow the inline script to be executed when Content Security Policy is enforced
56
- */
57
- nonce?: string;
58
- }
59
-
60
- export function createHydrationStreamProvider<TShape>() {
61
- const context = React.createContext<HydrationStreamContext<TShape>>(
62
- null as any,
63
- );
64
- /**
65
-
66
- * 1. (Happens on server): `useServerInsertedHTML()` is called **on the server** whenever a `Suspense`-boundary completes
67
- * - This means that we might have some new entries in the cache that needs to be flushed
68
- * - We pass these to the client by inserting a `<script>`-tag where we do `window[id].push(serializedVersionOfCache)`
69
- * 2. (Happens in browser) In `useEffect()`:
70
- * - We check if `window[id]` is set to an array and call `push()` on all the entries which will call `onEntries()` with the new entries
71
- * - We replace `window[id]` with a `push()`-method that will be called whenever new entries are received
72
- **/
73
- function UseClientHydrationStreamProvider(props: {
74
- children: React.ReactNode;
75
- /**
76
- * Optional transformer to serialize/deserialize the data
77
- * Example devalue, superjson et al
78
- */
79
- transformer?: DataTransformer;
80
- /**
81
- * **Client method**
82
- * Called in the browser when new entries are received
83
- */
84
- onEntries: (entries: Array<TShape>) => void;
85
- /**
86
- * **Server method**
87
- * onFlush is called on the server when the cache is flushed
88
- */
89
- onFlush?: () => Array<TShape>;
90
- /**
91
- * A nonce that'll allow the inline script to be executed when Content Security Policy is enforced
92
- */
93
- nonce?: string;
94
- }) {
95
- // unique id for the cache provider
96
- const id = `__RQ${React.useId()}`;
97
- const idJSON = htmlEscapeJsonString(JSON.stringify(id));
98
-
99
- const [transformer] = React.useState(
100
- () =>
101
- (props.transformer ?? {
102
- // noop
103
- serialize: (obj: any) => obj,
104
- deserialize: (obj: any) => obj,
105
- }) as unknown as TypedDataTransformer<TShape>,
106
- );
107
-
108
- // <server stuff>
109
- const [stream] = React.useState<Array<TShape>>(() => {
110
- if (!isServer) {
111
- return {
112
- push() {
113
- // no-op on the client
114
- },
115
- } as unknown as Array<TShape>;
116
- }
117
- return [];
118
- });
119
- const count = React.useRef(0);
120
- useServerInsertedHTML(() => {
121
- // This only happens on the server
122
- stream.push(...(props.onFlush?.() ?? []));
123
-
124
- if (!stream.length) {
125
- return null;
126
- }
127
- // console.log(`pushing ${stream.length} entries`)
128
- const serializedCacheArgs = stream
129
- .map((entry) => transformer.serialize(entry))
130
- .map((entry) => JSON.stringify(entry))
131
- .join(',');
132
-
133
- // Flush stream
134
- // eslint-disable-next-line react-hooks/immutability
135
- stream.length = 0;
136
-
137
- const html: Array<string> = [
138
- `window[${idJSON}] = window[${idJSON}] || [];`,
139
- `window[${idJSON}].push(${htmlEscapeJsonString(serializedCacheArgs)});`,
140
- ];
141
- return (
142
- <script
143
- key={count.current++}
144
- nonce={props.nonce}
145
- dangerouslySetInnerHTML={{
146
- __html: html.join(''),
147
- }}
148
- />
149
- );
150
- });
151
- // </server stuff>
152
-
153
- // <client stuff>
154
- // Setup and run the onEntries handler on the client only, but do it during
155
- // the initial render so children have access to the data immediately
156
- // This is important to avoid the client suspending during the initial render
157
- // if the data has not yet been hydrated.
158
- if (!isServer) {
159
- const win = window as any;
160
- if (!win[id]?.initialized) {
161
- // Client: consume cache:
162
- const onEntries = (...serializedEntries: Array<Serialized<TShape>>) => {
163
- const entries = serializedEntries.map((serialized) =>
164
- transformer.deserialize(serialized),
165
- );
166
- props.onEntries(entries);
167
- };
168
-
169
- const winStream: Array<Serialized<TShape>> = win[id] ?? [];
170
-
171
- onEntries(...winStream);
172
-
173
- // eslint-disable-next-line react-hooks/immutability
174
- win[id] = {
175
- initialized: true,
176
- push: onEntries,
177
- };
178
- }
179
- }
180
- // </client stuff>
181
-
182
- return (
183
- <context.Provider value={{ stream, id }}>
184
- {props.children}
185
- </context.Provider>
186
- );
187
- }
188
-
189
- return {
190
- Provider: UseClientHydrationStreamProvider,
191
- context,
192
- };
193
- }