@rocicorp/zero 0.16.2025022601 → 0.17.2025022800
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/out/{chunk-7E4L5D3N.js → chunk-5BT5TJFM.js} +517 -3962
- package/out/chunk-5BT5TJFM.js.map +7 -0
- package/out/chunk-P3NUVEQJ.js +3578 -0
- package/out/chunk-P3NUVEQJ.js.map +7 -0
- package/out/pg.js +593 -0
- package/out/pg.js.map +7 -0
- package/out/react.js +1 -4
- package/out/react.js.map +2 -2
- package/out/shared/src/types.js +2 -0
- package/out/shared/src/types.js.map +1 -0
- package/out/solid.js +3 -2
- package/out/solid.js.map +1 -1
- package/out/z2s/src/compiler.d.ts +26 -0
- package/out/z2s/src/compiler.d.ts.map +1 -0
- package/out/z2s/src/compiler.js +155 -0
- package/out/z2s/src/compiler.js.map +1 -0
- package/out/z2s/src/sql.d.ts +12 -0
- package/out/z2s/src/sql.d.ts.map +1 -0
- package/out/z2s/src/sql.js +18 -0
- package/out/z2s/src/sql.js.map +1 -0
- package/out/zero/src/pg.d.ts +2 -0
- package/out/zero/src/pg.d.ts.map +1 -0
- package/out/zero/src/pg.js +3 -0
- package/out/zero/src/pg.js.map +1 -0
- package/out/zero-cache/src/auth/load-permissions.d.ts +2 -2
- package/out/zero-cache/src/auth/load-permissions.d.ts.map +1 -1
- package/out/zero-cache/src/auth/load-permissions.js +6 -7
- package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
- package/out/zero-cache/src/auth/read-authorizer.d.ts.map +1 -1
- package/out/zero-cache/src/auth/read-authorizer.js +1 -1
- package/out/zero-cache/src/auth/read-authorizer.js.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.d.ts +1 -1
- package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.js +4 -2
- package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +1 -1
- package/out/zero-cache/src/config/zero-config.js +4 -4
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/scripts/deploy-permissions.js +5 -4
- package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +3 -2
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/main.d.ts.map +1 -1
- package/out/zero-cache/src/server/main.js +2 -1
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/server/multi/config.d.ts +1 -1
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +4 -3
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.d.ts +2 -2
- package/out/zero-cache/src/services/change-source/custom/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.js +10 -10
- package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/sync-schema.d.ts +1 -1
- package/out/zero-cache/src/services/change-source/custom/sync-schema.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/sync-schema.js +2 -2
- package/out/zero-cache/src/services/change-source/custom/sync-schema.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +14 -12
- package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +2 -2
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js +13 -9
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +11 -9
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts +2 -2
- package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js +10 -10
- package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts +1 -3
- package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/published.js +1 -3
- package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +10 -12
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js +55 -51
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/validation.d.ts +1 -0
- package/out/zero-cache/src/services/change-source/pg/schema/validation.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/validation.js +1 -0
- package/out/zero-cache/src/services/change-source/pg/schema/validation.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/sync-schema.d.ts +1 -1
- package/out/zero-cache/src/services/change-source/pg/sync-schema.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/sync-schema.js +2 -2
- package/out/zero-cache/src/services/change-source/pg/sync-schema.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js +1 -3
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts +2 -2
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +18 -14
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.js +5 -6
- package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +3 -3
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +4 -3
- package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +3 -3
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +12 -4
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts +1 -1
- package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/row-record-cache.js +2 -2
- package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts +3 -3
- package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.js +39 -39
- package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/init.d.ts +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/init.js +5 -5
- package/out/zero-cache/src/services/view-syncer/schema/init.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +4 -3
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +25 -23
- package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +12 -8
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-client/src/client/custom.d.ts +1 -1
- package/out/zero-client/src/client/custom.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.d.ts +1 -1
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/mod.d.ts +1 -0
- package/out/zero-client/src/mod.d.ts.map +1 -1
- package/out/zero-pg/src/custom.d.ts +42 -0
- package/out/zero-pg/src/custom.d.ts.map +1 -0
- package/out/zero-pg/src/custom.js +99 -0
- package/out/zero-pg/src/custom.js.map +1 -0
- package/out/zero-pg/src/db.d.ts +27 -0
- package/out/zero-pg/src/db.d.ts.map +1 -0
- package/out/zero-pg/src/db.js +2 -0
- package/out/zero-pg/src/db.js.map +1 -0
- package/out/zero-pg/src/logging.d.ts +3 -0
- package/out/zero-pg/src/logging.d.ts.map +1 -0
- package/out/zero-pg/src/logging.js +5 -0
- package/out/zero-pg/src/logging.js.map +1 -0
- package/out/zero-pg/src/mod.d.ts +5 -0
- package/out/zero-pg/src/mod.d.ts.map +1 -0
- package/out/zero-pg/src/mod.js +2 -0
- package/out/zero-pg/src/mod.js.map +1 -0
- package/out/zero-pg/src/query.d.ts +22 -0
- package/out/zero-pg/src/query.d.ts.map +1 -0
- package/out/zero-pg/src/query.js +54 -0
- package/out/zero-pg/src/query.js.map +1 -0
- package/out/zero-pg/src/web.d.ts +16 -0
- package/out/zero-pg/src/web.d.ts.map +1 -0
- package/out/zero-pg/src/web.js +115 -0
- package/out/zero-pg/src/web.js.map +1 -0
- package/out/zero-react/src/use-zero.d.ts +5 -4
- package/out/zero-react/src/use-zero.d.ts.map +1 -1
- package/out/zero.js +2 -1
- package/out/zql/src/ivm/exists.d.ts.map +1 -1
- package/out/zql/src/ivm/exists.js +43 -23
- package/out/zql/src/ivm/exists.js.map +1 -1
- package/out/zql/src/mutate/custom.js +10 -0
- package/out/zql/src/mutate/custom.js.map +1 -0
- package/out/zql/src/query/query-impl.d.ts +2 -2
- package/out/zql/src/query/query-impl.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.js +1 -1
- package/out/zql/src/query/query-impl.js.map +1 -1
- package/out/zql/src/query/query.d.ts +1 -1
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zql/src/query/static-query.d.ts +1 -1
- package/out/zql/src/query/static-query.d.ts.map +1 -1
- package/out/zql/src/query/static-query.js +3 -3
- package/out/zql/src/query/static-query.js.map +1 -1
- package/package.json +5 -1
- package/out/chunk-7E4L5D3N.js.map +0 -7
package/out/react.js
CHANGED
|
@@ -62,10 +62,7 @@ function useZero() {
|
|
|
62
62
|
function createUseZero() {
|
|
63
63
|
return () => useZero();
|
|
64
64
|
}
|
|
65
|
-
function ZeroProvider({
|
|
66
|
-
children,
|
|
67
|
-
zero
|
|
68
|
-
}) {
|
|
65
|
+
function ZeroProvider({ children, zero }) {
|
|
69
66
|
return /* @__PURE__ */ jsx(ZeroContext.Provider, { value: zero, children });
|
|
70
67
|
}
|
|
71
68
|
|
package/out/react.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../zero-react/src/use-query.tsx", "../../shared/src/deep-clone.ts", "../../zero-react/src/use-zero.tsx"],
|
|
4
|
-
"sourcesContent": ["import {useSyncExternalStore} from 'react';\nimport {deepClone} from '../../shared/src/deep-clone.ts';\nimport type {Immutable} from '../../shared/src/immutable.ts';\nimport type {ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport type {Schema} from '../../zero-schema/src/builder/schema-builder.ts';\nimport type {AdvancedQuery} from '../../zql/src/query/query-internal.ts';\nimport type {HumanReadable, Query} from '../../zql/src/query/query.ts';\nimport type {ResultType, TypedView} from '../../zql/src/query/typed-view.ts';\nimport {useZero} from './use-zero.tsx';\n\nexport type QueryResultDetails = Readonly<{\n type: ResultType;\n}>;\n\nexport type QueryResult<TReturn> = readonly [\n HumanReadable<TReturn>,\n QueryResultDetails,\n];\n\nexport function useQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n q: Query<TSchema, TTable, TReturn>,\n enable: boolean = true,\n): QueryResult<TReturn> {\n const z = useZero();\n const view = viewStore.getView(\n z.clientID,\n q as AdvancedQuery<TSchema, TTable, TReturn>,\n enable,\n );\n // https://react.dev/reference/react/useSyncExternalStore\n return useSyncExternalStore(\n view.subscribeReactInternals,\n view.getSnapshot,\n view.getSnapshot,\n );\n}\n\nconst emptyArray: unknown[] = [];\nconst disabledSubscriber = () => () => {};\n\nconst resultTypeUnknown = {type: 'unknown'} as const;\nconst resultTypeComplete = {type: 'complete'} as const;\n\nconst emptySnapshotSingularUnknown = [undefined, resultTypeUnknown] as const;\nconst emptySnapshotSingularComplete = [undefined, resultTypeComplete] as const;\nconst emptySnapshotPluralUnknown = [emptyArray, resultTypeUnknown] as const;\nconst emptySnapshotPluralComplete = [emptyArray, resultTypeComplete] as const;\n\nfunction getDefaultSnapshot<TReturn>(singular: boolean): QueryResult<TReturn> {\n return (\n singular ? emptySnapshotSingularUnknown : emptySnapshotPluralUnknown\n ) as QueryResult<TReturn>;\n}\n\n/**\n * Returns a new snapshot or one of the empty predefined ones. Returning the\n * predefined ones is important to prevent unnecessary re-renders in React.\n */\nfunction getSnapshot<TReturn>(\n singular: boolean,\n data: HumanReadable<TReturn>,\n resultType: string,\n): QueryResult<TReturn> {\n if (singular && data === undefined) {\n return (resultType === 'complete'\n ? emptySnapshotSingularComplete\n : emptySnapshotSingularUnknown) as unknown as QueryResult<TReturn>;\n }\n\n if (!singular && (data as unknown[]).length === 0) {\n return (\n resultType === 'complete'\n ? emptySnapshotPluralComplete\n : emptySnapshotPluralUnknown\n ) as QueryResult<TReturn>;\n }\n\n return [\n data,\n resultType === 'complete' ? resultTypeComplete : resultTypeUnknown,\n ];\n}\n\ndeclare const TESTING: boolean;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ViewWrapperAny = ViewWrapper<any, any, any>;\n\nconst allViews = new WeakMap<ViewStore, Map<string, ViewWrapperAny>>();\n\nexport function getAllViewsSizeForTesting(store: ViewStore): number {\n if (TESTING) {\n return allViews.get(store)?.size ?? 0;\n }\n return 0;\n}\n\n/**\n * A global store of all active views.\n *\n * React subscribes and unsubscribes to these views\n * via `useSyncExternalStore`.\n *\n * Managing views through `useEffect` or `useLayoutEffect` causes\n * inconsistencies because effects run after render.\n *\n * For example, if useQuery used use*Effect in the component below:\n * ```ts\n * function Foo({issueID}) {\n * const issue = useQuery(z.query.issue.where('id', issueID).one());\n * if (issue?.id !== undefined && issue.id !== issueID) {\n * console.log('MISMATCH!', issue.id, issueID);\n * }\n * }\n * ```\n *\n * `MISMATCH` will be printed whenever the `issueID` prop changes.\n *\n * This is because the component will render once with\n * the old state returned from `useQuery`. Then the effect inside\n * `useQuery` will run. The component will render again with the new\n * state. This inconsistent transition can cause unexpected results.\n *\n * Emulating `useEffect` via `useState` and `if` causes resource leaks.\n * That is:\n *\n * ```ts\n * function useQuery(q) {\n * const [oldHash, setOldHash] = useState();\n * if (hash(q) !== oldHash) {\n * // make new view\n * }\n *\n * useEffect(() => {\n * return () => view.destroy();\n * }, []);\n * }\n * ```\n *\n * I'm not sure why but in strict mode the cleanup function\n * fails to be called for the first instance of the view and only\n * cleans up later instances.\n *\n * Swapping `useState` to `useRef` has similar problems.\n */\nexport class ViewStore {\n #views = new Map<string, ViewWrapperAny>();\n\n constructor() {\n if (TESTING) {\n allViews.set(this, this.#views);\n }\n }\n\n getView<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n >(\n clientID: string,\n query: AdvancedQuery<TSchema, TTable, TReturn>,\n enabled: boolean,\n ): {\n getSnapshot: () => QueryResult<TReturn>;\n subscribeReactInternals: (internals: () => void) => () => void;\n } {\n if (!enabled) {\n return {\n getSnapshot: () => getDefaultSnapshot(query.format.singular),\n subscribeReactInternals: disabledSubscriber,\n };\n }\n\n const hash = query.hash() + clientID;\n let existing = this.#views.get(hash);\n if (!existing) {\n existing = new ViewWrapper(\n query,\n view => {\n const lastView = this.#views.get(hash);\n // I don't think this can happen\n // but lets guard against it so we don't\n // leak resources.\n if (lastView && lastView !== view) {\n throw new Error('View already exists');\n }\n this.#views.set(hash, view);\n },\n () => {\n this.#views.delete(hash);\n },\n ) as ViewWrapper<TSchema, TTable, TReturn>;\n this.#views.set(hash, existing);\n }\n return existing as ViewWrapper<TSchema, TTable, TReturn>;\n }\n}\n\nconst viewStore = new ViewStore();\n\n/**\n * This wraps and ref counts a view.\n *\n * The only signal we have from React as to whether or not it is\n * done with a view is when it calls `unsubscribe`.\n *\n * In non-strict-mode we can clean up the view as soon\n * as the listener count goes to 0.\n *\n * In strict-mode, the listener count will go to 0 then a\n * new listener for the same view is immediately added back.\n *\n * This is why the `onMaterialized` and `onDematerialized` callbacks exist --\n * they allow a view which React is still referencing to be added\n * back into the store when React re-subscribes to it.\n *\n * This wrapper also exists to deal with the various\n * `useSyncExternalStore` caveats that cause excessive\n * re-renders and materializations.\n *\n * See: https://react.dev/reference/react/useSyncExternalStore#caveats\n * Especially:\n * 1. The store snapshot returned by getSnapshot must be immutable. If the underlying store has mutable data, return a new immutable snapshot if the data has changed. Otherwise, return a cached last snapshot.\n * 2. If a different subscribe function is passed during a re-render, React will re-subscribe to the store using the newly passed subscribe function. You can prevent this by declaring subscribe outside the component.\n */\nclass ViewWrapper<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n> {\n #view: TypedView<HumanReadable<TReturn>> | undefined;\n readonly #onDematerialized;\n readonly #onMaterialized;\n readonly #query: AdvancedQuery<TSchema, TTable, TReturn>;\n #snapshot: QueryResult<TReturn>;\n #reactInternals: Set<() => void>;\n\n constructor(\n query: AdvancedQuery<TSchema, TTable, TReturn>,\n onMaterialized: (view: ViewWrapper<TSchema, TTable, TReturn>) => void,\n onDematerialized: () => void,\n ) {\n this.#snapshot = getDefaultSnapshot(query.format.singular);\n this.#onMaterialized = onMaterialized;\n this.#onDematerialized = onDematerialized;\n this.#reactInternals = new Set();\n this.#query = query;\n this.#materializeIfNeeded();\n }\n\n #onData = (\n snap: Immutable<HumanReadable<TReturn>>,\n resultType: ResultType,\n ) => {\n const data =\n snap === undefined\n ? snap\n : (deepClone(snap as ReadonlyJSONValue) as HumanReadable<TReturn>);\n this.#snapshot = getSnapshot(this.#query.format.singular, data, resultType);\n for (const internals of this.#reactInternals) {\n internals();\n }\n };\n\n #materializeIfNeeded = () => {\n if (this.#view) {\n return;\n }\n\n this.#view = this.#query.materialize();\n this.#view.addListener(this.#onData);\n\n this.#onMaterialized(this);\n };\n\n getSnapshot = () => this.#snapshot;\n\n subscribeReactInternals = (internals: () => void): (() => void) => {\n this.#reactInternals.add(internals);\n this.#materializeIfNeeded();\n return () => {\n this.#reactInternals.delete(internals);\n\n // only schedule a cleanup task if we have no listeners left\n if (this.#reactInternals.size === 0) {\n setTimeout(() => {\n // Someone re-registered a listener on this view before the timeout elapsed.\n // This happens often in strict-mode which forces a component\n // to mount, unmount, remount.\n if (this.#reactInternals.size > 0) {\n return;\n }\n // We already destroyed the view\n if (this.#view === undefined) {\n return;\n }\n this.#view?.destroy();\n this.#view = undefined;\n this.#onDematerialized();\n }, 10);\n }\n };\n };\n}\n", "import {hasOwn} from './has-own.ts';\nimport type {JSONValue, ReadonlyJSONValue} from './json.ts';\n\nexport function deepClone(value: ReadonlyJSONValue): JSONValue {\n const seen: Array<ReadonlyJSONValue> = [];\n return internalDeepClone(value, seen);\n}\n\nexport function internalDeepClone(\n value: ReadonlyJSONValue,\n seen: Array<ReadonlyJSONValue>,\n): JSONValue {\n switch (typeof value) {\n case 'boolean':\n case 'number':\n case 'string':\n case 'undefined':\n return value;\n case 'object': {\n if (value === null) {\n return null;\n }\n if (seen.includes(value)) {\n throw new Error('Cyclic object');\n }\n seen.push(value);\n if (Array.isArray(value)) {\n const rv = value.map(v => internalDeepClone(v, seen));\n seen.pop();\n return rv;\n }\n\n const obj: JSONValue = {};\n\n for (const k in value) {\n if (hasOwn(value, k)) {\n const v = (value as Record<string, ReadonlyJSONValue>)[k];\n if (v !== undefined) {\n obj[k] = internalDeepClone(v, seen);\n }\n }\n }\n seen.pop();\n return obj;\n }\n\n default:\n throw new Error(`Invalid type: ${typeof value}`);\n }\n}\n", "import {createContext, useContext} from 'react';\nimport type {Zero} from '../../zero-client/src/client/zero.ts';\nimport type {Schema} from '../../zero-schema/src/builder/schema-builder.ts';\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst ZeroContext = createContext<unknown | undefined>(undefined);\n\nexport function useZero<S extends Schema>(): Zero<S> {\n const zero = useContext(ZeroContext);\n if (zero === undefined) {\n throw new Error('useZero must be used within a ZeroProvider');\n }\n return zero as Zero<S>;\n}\n\nexport function createUseZero<S extends Schema>() {\n return () => useZero<S>();\n}\n\nexport function ZeroProvider<S extends Schema>({\n children,\n zero,\n}: {\n children: React.ReactNode;\n zero: Zero<S>;\n}) {\n return <ZeroContext.Provider value={zero}>{children}</ZeroContext.Provider>;\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;AAAA,SAAQ,4BAA2B;;;ACG5B,SAAS,UAAU,OAAqC;AAC7D,QAAM,OAAiC,CAAC;AACxC,SAAO,kBAAkB,OAAO,IAAI;AACtC;AAEO,SAAS,kBACd,OACA,MACW;AACX,UAAQ,OAAO,OAAO;AAAA,IACpB,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK,UAAU;AACb,UAAI,UAAU,MAAM;AAClB,eAAO;AAAA,MACT;AACA,UAAI,KAAK,SAAS,KAAK,GAAG;AACxB,cAAM,IAAI,MAAM,eAAe;AAAA,MACjC;AACA,WAAK,KAAK,KAAK;AACf,UAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,cAAM,KAAK,MAAM,IAAI,OAAK,kBAAkB,GAAG,IAAI,CAAC;AACpD,aAAK,IAAI;AACT,eAAO;AAAA,MACT;AAEA,YAAM,MAAiB,CAAC;AAExB,iBAAW,KAAK,OAAO;AACrB,YAAI,OAAO,OAAO,CAAC,GAAG;AACpB,gBAAM,IAAK,MAA4C,CAAC;AACxD,cAAI,MAAM,QAAW;AACnB,gBAAI,CAAC,IAAI,kBAAkB,GAAG,IAAI;AAAA,UACpC;AAAA,QACF;AAAA,MACF;AACA,WAAK,IAAI;AACT,aAAO;AAAA,IACT;AAAA,IAEA;AACE,YAAM,IAAI,MAAM,iBAAiB,OAAO,KAAK,EAAE;AAAA,EACnD;AACF;;;ACjDA,SAAQ,eAAe,kBAAiB;
|
|
4
|
+
"sourcesContent": ["import {useSyncExternalStore} from 'react';\nimport {deepClone} from '../../shared/src/deep-clone.ts';\nimport type {Immutable} from '../../shared/src/immutable.ts';\nimport type {ReadonlyJSONValue} from '../../shared/src/json.ts';\nimport type {Schema} from '../../zero-schema/src/builder/schema-builder.ts';\nimport type {AdvancedQuery} from '../../zql/src/query/query-internal.ts';\nimport type {HumanReadable, Query} from '../../zql/src/query/query.ts';\nimport type {ResultType, TypedView} from '../../zql/src/query/typed-view.ts';\nimport {useZero} from './use-zero.tsx';\n\nexport type QueryResultDetails = Readonly<{\n type: ResultType;\n}>;\n\nexport type QueryResult<TReturn> = readonly [\n HumanReadable<TReturn>,\n QueryResultDetails,\n];\n\nexport function useQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n q: Query<TSchema, TTable, TReturn>,\n enable: boolean = true,\n): QueryResult<TReturn> {\n const z = useZero();\n const view = viewStore.getView(\n z.clientID,\n q as AdvancedQuery<TSchema, TTable, TReturn>,\n enable,\n );\n // https://react.dev/reference/react/useSyncExternalStore\n return useSyncExternalStore(\n view.subscribeReactInternals,\n view.getSnapshot,\n view.getSnapshot,\n );\n}\n\nconst emptyArray: unknown[] = [];\nconst disabledSubscriber = () => () => {};\n\nconst resultTypeUnknown = {type: 'unknown'} as const;\nconst resultTypeComplete = {type: 'complete'} as const;\n\nconst emptySnapshotSingularUnknown = [undefined, resultTypeUnknown] as const;\nconst emptySnapshotSingularComplete = [undefined, resultTypeComplete] as const;\nconst emptySnapshotPluralUnknown = [emptyArray, resultTypeUnknown] as const;\nconst emptySnapshotPluralComplete = [emptyArray, resultTypeComplete] as const;\n\nfunction getDefaultSnapshot<TReturn>(singular: boolean): QueryResult<TReturn> {\n return (\n singular ? emptySnapshotSingularUnknown : emptySnapshotPluralUnknown\n ) as QueryResult<TReturn>;\n}\n\n/**\n * Returns a new snapshot or one of the empty predefined ones. Returning the\n * predefined ones is important to prevent unnecessary re-renders in React.\n */\nfunction getSnapshot<TReturn>(\n singular: boolean,\n data: HumanReadable<TReturn>,\n resultType: string,\n): QueryResult<TReturn> {\n if (singular && data === undefined) {\n return (resultType === 'complete'\n ? emptySnapshotSingularComplete\n : emptySnapshotSingularUnknown) as unknown as QueryResult<TReturn>;\n }\n\n if (!singular && (data as unknown[]).length === 0) {\n return (\n resultType === 'complete'\n ? emptySnapshotPluralComplete\n : emptySnapshotPluralUnknown\n ) as QueryResult<TReturn>;\n }\n\n return [\n data,\n resultType === 'complete' ? resultTypeComplete : resultTypeUnknown,\n ];\n}\n\ndeclare const TESTING: boolean;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ViewWrapperAny = ViewWrapper<any, any, any>;\n\nconst allViews = new WeakMap<ViewStore, Map<string, ViewWrapperAny>>();\n\nexport function getAllViewsSizeForTesting(store: ViewStore): number {\n if (TESTING) {\n return allViews.get(store)?.size ?? 0;\n }\n return 0;\n}\n\n/**\n * A global store of all active views.\n *\n * React subscribes and unsubscribes to these views\n * via `useSyncExternalStore`.\n *\n * Managing views through `useEffect` or `useLayoutEffect` causes\n * inconsistencies because effects run after render.\n *\n * For example, if useQuery used use*Effect in the component below:\n * ```ts\n * function Foo({issueID}) {\n * const issue = useQuery(z.query.issue.where('id', issueID).one());\n * if (issue?.id !== undefined && issue.id !== issueID) {\n * console.log('MISMATCH!', issue.id, issueID);\n * }\n * }\n * ```\n *\n * `MISMATCH` will be printed whenever the `issueID` prop changes.\n *\n * This is because the component will render once with\n * the old state returned from `useQuery`. Then the effect inside\n * `useQuery` will run. The component will render again with the new\n * state. This inconsistent transition can cause unexpected results.\n *\n * Emulating `useEffect` via `useState` and `if` causes resource leaks.\n * That is:\n *\n * ```ts\n * function useQuery(q) {\n * const [oldHash, setOldHash] = useState();\n * if (hash(q) !== oldHash) {\n * // make new view\n * }\n *\n * useEffect(() => {\n * return () => view.destroy();\n * }, []);\n * }\n * ```\n *\n * I'm not sure why but in strict mode the cleanup function\n * fails to be called for the first instance of the view and only\n * cleans up later instances.\n *\n * Swapping `useState` to `useRef` has similar problems.\n */\nexport class ViewStore {\n #views = new Map<string, ViewWrapperAny>();\n\n constructor() {\n if (TESTING) {\n allViews.set(this, this.#views);\n }\n }\n\n getView<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n >(\n clientID: string,\n query: AdvancedQuery<TSchema, TTable, TReturn>,\n enabled: boolean,\n ): {\n getSnapshot: () => QueryResult<TReturn>;\n subscribeReactInternals: (internals: () => void) => () => void;\n } {\n if (!enabled) {\n return {\n getSnapshot: () => getDefaultSnapshot(query.format.singular),\n subscribeReactInternals: disabledSubscriber,\n };\n }\n\n const hash = query.hash() + clientID;\n let existing = this.#views.get(hash);\n if (!existing) {\n existing = new ViewWrapper(\n query,\n view => {\n const lastView = this.#views.get(hash);\n // I don't think this can happen\n // but lets guard against it so we don't\n // leak resources.\n if (lastView && lastView !== view) {\n throw new Error('View already exists');\n }\n this.#views.set(hash, view);\n },\n () => {\n this.#views.delete(hash);\n },\n ) as ViewWrapper<TSchema, TTable, TReturn>;\n this.#views.set(hash, existing);\n }\n return existing as ViewWrapper<TSchema, TTable, TReturn>;\n }\n}\n\nconst viewStore = new ViewStore();\n\n/**\n * This wraps and ref counts a view.\n *\n * The only signal we have from React as to whether or not it is\n * done with a view is when it calls `unsubscribe`.\n *\n * In non-strict-mode we can clean up the view as soon\n * as the listener count goes to 0.\n *\n * In strict-mode, the listener count will go to 0 then a\n * new listener for the same view is immediately added back.\n *\n * This is why the `onMaterialized` and `onDematerialized` callbacks exist --\n * they allow a view which React is still referencing to be added\n * back into the store when React re-subscribes to it.\n *\n * This wrapper also exists to deal with the various\n * `useSyncExternalStore` caveats that cause excessive\n * re-renders and materializations.\n *\n * See: https://react.dev/reference/react/useSyncExternalStore#caveats\n * Especially:\n * 1. The store snapshot returned by getSnapshot must be immutable. If the underlying store has mutable data, return a new immutable snapshot if the data has changed. Otherwise, return a cached last snapshot.\n * 2. If a different subscribe function is passed during a re-render, React will re-subscribe to the store using the newly passed subscribe function. You can prevent this by declaring subscribe outside the component.\n */\nclass ViewWrapper<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n> {\n #view: TypedView<HumanReadable<TReturn>> | undefined;\n readonly #onDematerialized;\n readonly #onMaterialized;\n readonly #query: AdvancedQuery<TSchema, TTable, TReturn>;\n #snapshot: QueryResult<TReturn>;\n #reactInternals: Set<() => void>;\n\n constructor(\n query: AdvancedQuery<TSchema, TTable, TReturn>,\n onMaterialized: (view: ViewWrapper<TSchema, TTable, TReturn>) => void,\n onDematerialized: () => void,\n ) {\n this.#snapshot = getDefaultSnapshot(query.format.singular);\n this.#onMaterialized = onMaterialized;\n this.#onDematerialized = onDematerialized;\n this.#reactInternals = new Set();\n this.#query = query;\n this.#materializeIfNeeded();\n }\n\n #onData = (\n snap: Immutable<HumanReadable<TReturn>>,\n resultType: ResultType,\n ) => {\n const data =\n snap === undefined\n ? snap\n : (deepClone(snap as ReadonlyJSONValue) as HumanReadable<TReturn>);\n this.#snapshot = getSnapshot(this.#query.format.singular, data, resultType);\n for (const internals of this.#reactInternals) {\n internals();\n }\n };\n\n #materializeIfNeeded = () => {\n if (this.#view) {\n return;\n }\n\n this.#view = this.#query.materialize();\n this.#view.addListener(this.#onData);\n\n this.#onMaterialized(this);\n };\n\n getSnapshot = () => this.#snapshot;\n\n subscribeReactInternals = (internals: () => void): (() => void) => {\n this.#reactInternals.add(internals);\n this.#materializeIfNeeded();\n return () => {\n this.#reactInternals.delete(internals);\n\n // only schedule a cleanup task if we have no listeners left\n if (this.#reactInternals.size === 0) {\n setTimeout(() => {\n // Someone re-registered a listener on this view before the timeout elapsed.\n // This happens often in strict-mode which forces a component\n // to mount, unmount, remount.\n if (this.#reactInternals.size > 0) {\n return;\n }\n // We already destroyed the view\n if (this.#view === undefined) {\n return;\n }\n this.#view?.destroy();\n this.#view = undefined;\n this.#onDematerialized();\n }, 10);\n }\n };\n };\n}\n", "import {hasOwn} from './has-own.ts';\nimport type {JSONValue, ReadonlyJSONValue} from './json.ts';\n\nexport function deepClone(value: ReadonlyJSONValue): JSONValue {\n const seen: Array<ReadonlyJSONValue> = [];\n return internalDeepClone(value, seen);\n}\n\nexport function internalDeepClone(\n value: ReadonlyJSONValue,\n seen: Array<ReadonlyJSONValue>,\n): JSONValue {\n switch (typeof value) {\n case 'boolean':\n case 'number':\n case 'string':\n case 'undefined':\n return value;\n case 'object': {\n if (value === null) {\n return null;\n }\n if (seen.includes(value)) {\n throw new Error('Cyclic object');\n }\n seen.push(value);\n if (Array.isArray(value)) {\n const rv = value.map(v => internalDeepClone(v, seen));\n seen.pop();\n return rv;\n }\n\n const obj: JSONValue = {};\n\n for (const k in value) {\n if (hasOwn(value, k)) {\n const v = (value as Record<string, ReadonlyJSONValue>)[k];\n if (v !== undefined) {\n obj[k] = internalDeepClone(v, seen);\n }\n }\n }\n seen.pop();\n return obj;\n }\n\n default:\n throw new Error(`Invalid type: ${typeof value}`);\n }\n}\n", "import {createContext, useContext} from 'react';\nimport type {Zero} from '../../zero-client/src/client/zero.ts';\nimport type {Schema} from '../../zero-schema/src/builder/schema-builder.ts';\nimport type {CustomMutatorDefs} from '../../zero-client/src/client/custom.ts';\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nconst ZeroContext = createContext<unknown | undefined>(undefined);\n\nexport function useZero<\n S extends Schema,\n MD extends CustomMutatorDefs<S> | undefined = undefined,\n>(): Zero<S, MD> {\n const zero = useContext(ZeroContext);\n if (zero === undefined) {\n throw new Error('useZero must be used within a ZeroProvider');\n }\n return zero as Zero<S, MD>;\n}\n\nexport function createUseZero<\n S extends Schema,\n MD extends CustomMutatorDefs<S> | undefined = undefined,\n>() {\n return () => useZero<S, MD>();\n}\n\nexport function ZeroProvider<\n S extends Schema,\n MD extends CustomMutatorDefs<S> | undefined = undefined,\n>({children, zero}: {children: React.ReactNode; zero: Zero<S, MD>}) {\n return <ZeroContext.Provider value={zero}>{children}</ZeroContext.Provider>;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../shared/src/types.ts"],"names":[],"mappings":""}
|
package/out/solid.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Zero
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-HARIWJ2J.js";
|
|
3
|
+
} from "./chunk-5BT5TJFM.js";
|
|
5
4
|
import "./chunk-ULOTOBTC.js";
|
|
5
|
+
import "./chunk-P3NUVEQJ.js";
|
|
6
|
+
import "./chunk-HARIWJ2J.js";
|
|
6
7
|
import {
|
|
7
8
|
applyChange
|
|
8
9
|
} from "./chunk-Q6D7EOS6.js";
|
package/out/solid.js.map
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../zero-solid/src/create-zero.ts", "../../zero-solid/src/use-query.ts", "../../zero-solid/src/solid-view.ts"],
|
|
4
4
|
"sourcesContent": ["import {batch} from 'solid-js';\nimport type {ZeroAdvancedOptions} from '../../zero/src/advanced.ts';\nimport {Zero, type Schema, type ZeroOptions} from '../../zero/src/zero.ts';\n\nexport function createZero<S extends Schema>(options: ZeroOptions<S>): Zero<S> {\n const opts: ZeroAdvancedOptions<S> = {\n ...options,\n batchViewUpdates: batch,\n };\n return new Zero(opts);\n}\n", "import {createMemo, onCleanup, type Accessor} from 'solid-js';\nimport type {\n AdvancedQuery,\n HumanReadable,\n Query,\n} from '../../zero/src/advanced.ts';\nimport type {Schema} from '../../zero/src/zero.ts';\nimport {solidViewFactory, type QueryResultDetails} from './solid-view.ts';\n\nexport type QueryResult<TReturn> = readonly [\n Accessor<HumanReadable<TReturn>>,\n Accessor<QueryResultDetails>,\n];\n\nexport function useQuery<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(querySignal: () => Query<TSchema, TTable, TReturn>): QueryResult<TReturn> {\n // Wrap in in createMemo to ensure a new view is created if the querySignal changes.\n const view = createMemo(() => {\n const query = querySignal();\n const view = (query as AdvancedQuery<TSchema, TTable, TReturn>).materialize(\n solidViewFactory,\n );\n\n onCleanup(() => {\n view.destroy();\n });\n return view;\n });\n\n return [() => view().data, () => view().resultDetails];\n}\n", "import {\n createStore,\n produce,\n type SetStoreFunction,\n type Store,\n} from 'solid-js/store';\nimport {\n applyChange,\n type Change,\n type Entry,\n type Format,\n type HumanReadable,\n type Input,\n type Output,\n type Query,\n type ViewFactory,\n} from '../../zero-advanced/src/mod.js';\nimport type {Schema} from '../../zero-schema/src/mod.js';\nimport type {ResultType} from '../../zql/src/query/typed-view.js';\nimport type {Node} from '../../zql/src/ivm/data.ts';\nimport type {ViewChange} from '../../zql/src/ivm/view-apply-change.ts';\nimport type {Stream} from '../../zql/src/ivm/stream.ts';\n\nexport type QueryResultDetails = {\n readonly type: ResultType;\n};\n\ntype State = [Entry, QueryResultDetails];\n\nconst complete = {type: 'complete'} as const;\nconst unknown = {type: 'unknown'} as const;\n\nexport class SolidView<V> implements Output {\n readonly #input: Input;\n readonly #format: Format;\n readonly #onDestroy: () => void;\n\n #state: Store<State>;\n #setState: SetStoreFunction<State>;\n\n // Optimization: if the store is currently empty we build up\n // the view on a plain old JS object stored at #builderRoot, and return\n // that for the new state on transaction commit. This avoids building up\n // large views from scratch via solid produce. The proxy object used by\n // solid produce is slow and in this case we don't care about solid tracking\n // the fine grained changes (everything has changed, it's all new). For a\n // test case with a view with 3000 rows, each row having 2 children, this\n // optimization reduced #applyChanges time from 743ms to 133ms.\n #builderRoot: Entry | undefined;\n #pendingChanges: ViewChange[] = [];\n\n constructor(\n input: Input,\n onTransactionCommit: (cb: () => void) => void,\n format: Format,\n onDestroy: () => void,\n queryComplete: true | Promise<true>,\n ) {\n this.#input = input;\n onTransactionCommit(this.#onTransactionCommit);\n this.#format = format;\n this.#onDestroy = onDestroy;\n input.setOutput(this);\n\n const initialRoot = this.#createEmptyRoot();\n this.#applyChangesToRoot(\n input.fetch({}),\n node => ({type: 'add', node}),\n initialRoot,\n );\n [this.#state, this.#setState] = createStore<State>([\n initialRoot,\n queryComplete === true ? complete : unknown,\n ]);\n if (isEmptyRoot(initialRoot)) {\n this.#builderRoot = this.#createEmptyRoot();\n }\n\n if (queryComplete !== true) {\n void queryComplete.then(() => {\n this.#setState(oldState => [oldState[0], complete]);\n });\n }\n }\n\n get data(): V {\n return this.#state[0][''] as V;\n }\n\n get resultDetails(): QueryResultDetails {\n return this.#state[1];\n }\n\n destroy(): void {\n this.#onDestroy();\n }\n\n #onTransactionCommit = () => {\n const builderRoot = this.#builderRoot;\n if (builderRoot) {\n if (!isEmptyRoot(builderRoot)) {\n this.#setState(oldState => [builderRoot, oldState[1]]);\n this.#builderRoot = undefined;\n }\n } else {\n try {\n this.#applyChanges(this.#pendingChanges, c => c);\n } finally {\n this.#pendingChanges = [];\n }\n }\n };\n\n push(change: Change): void {\n // Delay updating the solid store state until the transaction commit\n // (because each update of the solid store is quite expensive). If\n // this.#builderRoot is defined apply the changes to it (we are building\n // from an empty root), otherwise queue the changes to be applied\n // using produce at the end of the transaction but read the relationships\n // now as they are only valid to read when the push is received.\n if (this.#builderRoot) {\n this.#applyChangeToRoot(change, this.#builderRoot);\n } else {\n this.#pendingChanges.push(materializeRelationships(change));\n }\n }\n\n #applyChanges<T>(changes: Iterable<T>, mapper: (v: T) => ViewChange): void {\n this.#setState(\n produce((draftState: State) => {\n this.#applyChangesToRoot<T>(changes, mapper, draftState[0]);\n if (isEmptyRoot(draftState[0])) {\n this.#builderRoot = this.#createEmptyRoot();\n }\n }),\n );\n }\n\n #applyChangesToRoot<T>(\n changes: Iterable<T>,\n mapper: (v: T) => ViewChange,\n root: Entry,\n ) {\n for (const change of changes) {\n this.#applyChangeToRoot(mapper(change), root);\n }\n }\n\n #applyChangeToRoot(change: ViewChange, root: Entry) {\n applyChange(root, change, this.#input.getSchema(), '', this.#format);\n }\n\n #createEmptyRoot(): Entry {\n return {\n '': this.#format.singular ? undefined : [],\n };\n }\n}\n\nfunction materializeRelationships(change: Change): ViewChange {\n switch (change.type) {\n case 'add':\n return {type: 'add', node: materializeNodeRelationships(change.node)};\n case 'remove':\n return {type: 'remove', node: materializeNodeRelationships(change.node)};\n case 'child':\n return {\n type: 'child',\n node: {row: change.node.row},\n child: {\n relationshipName: change.child.relationshipName,\n change: materializeRelationships(change.child.change),\n },\n };\n case 'edit':\n return {\n type: 'edit',\n node: {row: change.node.row},\n oldNode: {row: change.oldNode.row},\n };\n }\n}\n\nfunction materializeNodeRelationships(node: Node): Node {\n const relationships: Record<string, () => Stream<Node>> = {};\n for (const relationship in node.relationships) {\n const materialized: Node[] = [];\n for (const n of node.relationships[relationship]()) {\n materialized.push(materializeNodeRelationships(n));\n }\n relationships[relationship] = () => materialized;\n }\n return {\n row: node.row,\n relationships,\n };\n}\n\nfunction isEmptyRoot(entry: Entry) {\n const data = entry[''];\n return data === undefined || (Array.isArray(data) && data.length === 0);\n}\n\nexport function solidViewFactory<\n TSchema extends Schema,\n TTable extends keyof TSchema['tables'] & string,\n TReturn,\n>(\n _query: Query<TSchema, TTable, TReturn>,\n input: Input,\n format: Format,\n onDestroy: () => void,\n onTransactionCommit: (cb: () => void) => void,\n queryComplete: true | Promise<true>,\n) {\n return new SolidView<HumanReadable<TReturn>>(\n input,\n onTransactionCommit,\n format,\n onDestroy,\n queryComplete,\n );\n}\n\nsolidViewFactory satisfies ViewFactory<Schema, string, unknown, unknown>;\n"],
|
|
5
|
-
"mappings": "
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["view"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CorrelatedSubqueryCondition, Correlation, Ordering, ValuePosition } from '../../zero-protocol/src/ast.ts';
|
|
2
|
+
import { type AST, type Condition, type CorrelatedSubquery, type SimpleCondition } from '../../zero-protocol/src/ast.ts';
|
|
3
|
+
import type { Format } from '../../zql/src/ivm/view.ts';
|
|
4
|
+
import type { SQLQuery } from '@databases/sql';
|
|
5
|
+
/**
|
|
6
|
+
* Compiles to the Postgres dialect of SQL
|
|
7
|
+
* - IS, IS NOT can only compare against `NULL`, `TRUE`, `FALSE` so use
|
|
8
|
+
* `IS DISTINCT FROM` and `IS NOT DISTINCT FROM` instead
|
|
9
|
+
* - IN is changed to ANY to allow binding array literals
|
|
10
|
+
* - subqueries are aggregated using PG's `array_agg` and `row_to_json` functions
|
|
11
|
+
*/
|
|
12
|
+
export declare function compile(ast: AST, format?: Format | undefined): SQLQuery;
|
|
13
|
+
export declare function select(ast: AST, format: Format | undefined, correlation: SQLQuery | undefined): SQLQuery;
|
|
14
|
+
export declare function orderBy(orderBy: Ordering | undefined): SQLQuery;
|
|
15
|
+
export declare function limit(limit: number | undefined): SQLQuery;
|
|
16
|
+
export declare function related(relationships: readonly CorrelatedSubquery[], format: Format | undefined, parentTable: string): SQLQuery[];
|
|
17
|
+
export declare function pullTablesForJunction(relationship: CorrelatedSubquery, tables?: [string, Correlation, number | undefined][]): [string, Correlation, number | undefined][];
|
|
18
|
+
export declare function makeJunctionJoin(relationship: CorrelatedSubquery): [join: SQLQuery, lastAlis: string, lastLimit: number | undefined];
|
|
19
|
+
export declare function where(condition: Condition | undefined, parentTable: string): SQLQuery;
|
|
20
|
+
export declare function simple(condition: SimpleCondition): SQLQuery;
|
|
21
|
+
export declare function distinctFrom(condition: SimpleCondition): SQLQuery;
|
|
22
|
+
export declare function any(condition: SimpleCondition): SQLQuery;
|
|
23
|
+
export declare function valuePosition(value: ValuePosition): SQLQuery;
|
|
24
|
+
export declare function exists(condition: CorrelatedSubqueryCondition, parentTable: string): SQLQuery;
|
|
25
|
+
export declare function correlate(parentTable: string, parentColumns: readonly string[], childTable: string, childColumns: readonly string[]): SQLQuery;
|
|
26
|
+
//# sourceMappingURL=compiler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../../z2s/src/compiler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,2BAA2B,EAC3B,WAAW,EACX,QAAQ,EACR,aAAa,EACd,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,KAAK,GAAG,EACR,KAAK,SAAS,EACd,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACrB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,2BAA2B,CAAC;AAEtD,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAE7C;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,YAE5D;AAED,wBAAgB,MAAM,CACpB,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,WAAW,EAAE,QAAQ,GAAG,SAAS,YAWlC;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAU/D;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAKzD;AAED,wBAAgB,OAAO,CACrB,aAAa,EAAE,SAAS,kBAAkB,EAAE,EAC5C,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,WAAW,EAAE,MAAM,GAClB,QAAQ,EAAE,CAQZ;AA+CD,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,kBAAkB,EAChC,MAAM,GAAE,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC,EAAO,+CAezD;AAED,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,kBAAkB,GAC/B,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,CAiCnE;AAED,wBAAgB,KAAK,CACnB,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,WAAW,EAAE,MAAM,GAClB,QAAQ,CAqBV;AAED,wBAAgB,MAAM,CAAC,SAAS,EAAE,eAAe,GAAG,QAAQ,CAsB3D;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,eAAe,GAAG,QAAQ,CAIjE;AAED,wBAAgB,GAAG,CAAC,SAAS,EAAE,eAAe,GAAG,QAAQ,CAIxD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,QAAQ,CAW5D;AAED,wBAAgB,MAAM,CACpB,SAAS,EAAE,2BAA2B,EACtC,WAAW,EAAE,MAAM,GAClB,QAAQ,CAoBV;AAED,wBAAgB,SAAS,CACvB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,SAAS,MAAM,EAAE,EAChC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,SAAS,MAAM,EAAE,YAWhC"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { assert } from "../../shared/src/asserts.js";
|
|
2
|
+
import { must } from "../../shared/src/must.js";
|
|
3
|
+
import {} from "../../zero-protocol/src/ast.js";
|
|
4
|
+
import { sql } from "./sql.js";
|
|
5
|
+
/**
|
|
6
|
+
* Compiles to the Postgres dialect of SQL
|
|
7
|
+
* - IS, IS NOT can only compare against `NULL`, `TRUE`, `FALSE` so use
|
|
8
|
+
* `IS DISTINCT FROM` and `IS NOT DISTINCT FROM` instead
|
|
9
|
+
* - IN is changed to ANY to allow binding array literals
|
|
10
|
+
* - subqueries are aggregated using PG's `array_agg` and `row_to_json` functions
|
|
11
|
+
*/
|
|
12
|
+
export function compile(ast, format) {
|
|
13
|
+
return select(ast, format, undefined);
|
|
14
|
+
}
|
|
15
|
+
export function select(ast, format, correlation) {
|
|
16
|
+
const selectionSet = related(ast.related ?? [], format, ast.table);
|
|
17
|
+
selectionSet.push(sql `*`);
|
|
18
|
+
return sql `SELECT ${sql.join(selectionSet, ',')} FROM ${sql.ident(ast.table)} ${ast.where ? sql `WHERE ${where(ast.where, ast.table)}` : sql ``} ${correlation
|
|
19
|
+
? sql `${ast.where ? sql `AND` : sql `WHERE`} (${correlation})`
|
|
20
|
+
: sql ``} ${orderBy(ast.orderBy)} ${format?.singular ? limit(1) : limit(ast.limit)}`;
|
|
21
|
+
}
|
|
22
|
+
export function orderBy(orderBy) {
|
|
23
|
+
if (!orderBy) {
|
|
24
|
+
return sql ``;
|
|
25
|
+
}
|
|
26
|
+
return sql `ORDER BY ${sql.join(orderBy.map(([col, dir]) => dir === 'asc' ? sql `${sql.ident(col)} ASC` : sql `${sql.ident(col)} DESC`), ', ')}`;
|
|
27
|
+
}
|
|
28
|
+
export function limit(limit) {
|
|
29
|
+
if (!limit) {
|
|
30
|
+
return sql ``;
|
|
31
|
+
}
|
|
32
|
+
return sql `LIMIT ${sql.value(limit)}`;
|
|
33
|
+
}
|
|
34
|
+
export function related(relationships, format, parentTable) {
|
|
35
|
+
return relationships.map(relationship => relationshipSubquery(relationship, format?.relationships[must(relationship.subquery.alias)], parentTable));
|
|
36
|
+
}
|
|
37
|
+
function relationshipSubquery(relationship, format, parentTable) {
|
|
38
|
+
if (relationship.hidden) {
|
|
39
|
+
const [join, lastAlias, lastLimit] = makeJunctionJoin(relationship);
|
|
40
|
+
return sql `(
|
|
41
|
+
SELECT ${format?.singular ? sql `` : sql `COALESCE(array_agg`}(row_to_json(${sql.ident(`inner_${relationship.subquery.alias}`)})) ${format?.singular ? sql `` : sql `, ARRAY[]::json[])`} FROM (SELECT ${sql.ident(lastAlias)}.* FROM ${join} WHERE (${correlate(parentTable, relationship.correlation.parentField, relationship.subquery.table, relationship.correlation.childField)}) ${relationship.subquery.where
|
|
42
|
+
? sql `AND ${where(relationship.subquery.where, relationship.subquery.table)}`
|
|
43
|
+
: sql ``} ${orderBy(relationship.subquery.orderBy)} ${format?.singular ? limit(1) : limit(lastLimit)} ) ${sql.ident(`inner_${relationship.subquery.alias}`)}
|
|
44
|
+
) as ${sql.ident(relationship.subquery.alias)}`;
|
|
45
|
+
}
|
|
46
|
+
return sql `(
|
|
47
|
+
SELECT ${format?.singular ? sql `` : sql `array_agg`}(row_to_json(${sql.ident(`inner_${relationship.subquery.alias}`)})) FROM (${select(relationship.subquery, format, correlate(parentTable, relationship.correlation.parentField, relationship.subquery.table, relationship.correlation.childField))}) ${sql.ident(`inner_${relationship.subquery.alias}`)}
|
|
48
|
+
) as ${sql.ident(relationship.subquery.alias)}`;
|
|
49
|
+
}
|
|
50
|
+
export function pullTablesForJunction(relationship, tables = []) {
|
|
51
|
+
tables.push([
|
|
52
|
+
relationship.subquery.table,
|
|
53
|
+
relationship.correlation,
|
|
54
|
+
relationship.subquery.limit,
|
|
55
|
+
]);
|
|
56
|
+
assert(relationship.subquery.related?.length || 0 <= 1, 'Too many related tables for a junction edge');
|
|
57
|
+
for (const subRelationship of relationship.subquery.related ?? []) {
|
|
58
|
+
pullTablesForJunction(subRelationship, tables);
|
|
59
|
+
}
|
|
60
|
+
return tables;
|
|
61
|
+
}
|
|
62
|
+
export function makeJunctionJoin(relationship) {
|
|
63
|
+
const participatingTables = pullTablesForJunction(relationship);
|
|
64
|
+
const ret = [];
|
|
65
|
+
function alias(index) {
|
|
66
|
+
if (index === 0) {
|
|
67
|
+
return participatingTables[0][0];
|
|
68
|
+
}
|
|
69
|
+
return `table_${index}`;
|
|
70
|
+
}
|
|
71
|
+
for (const [table, _correlation] of participatingTables) {
|
|
72
|
+
if (ret.length === 0) {
|
|
73
|
+
ret.push(sql.ident(table));
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
ret.push(sql ` JOIN ${sql.ident(table)} as ${sql.ident(alias(ret.length))} ON ${correlate(alias(ret.length - 1), participatingTables[ret.length][1].parentField, alias(ret.length), participatingTables[ret.length][1].childField)}`);
|
|
77
|
+
}
|
|
78
|
+
return [
|
|
79
|
+
sql.join(ret, ''),
|
|
80
|
+
alias(ret.length - 1),
|
|
81
|
+
participatingTables[participatingTables.length - 1][2],
|
|
82
|
+
];
|
|
83
|
+
}
|
|
84
|
+
export function where(condition, parentTable) {
|
|
85
|
+
if (!condition) {
|
|
86
|
+
return sql ``;
|
|
87
|
+
}
|
|
88
|
+
switch (condition.type) {
|
|
89
|
+
case 'and':
|
|
90
|
+
return sql `(${sql.join(condition.conditions.map(c => where(c, parentTable)), ' AND ')})`;
|
|
91
|
+
case 'or':
|
|
92
|
+
return sql `(${sql.join(condition.conditions.map(c => where(c, parentTable)), ' OR ')})`;
|
|
93
|
+
case 'correlatedSubquery':
|
|
94
|
+
return exists(condition, parentTable);
|
|
95
|
+
case 'simple':
|
|
96
|
+
return simple(condition);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export function simple(condition) {
|
|
100
|
+
switch (condition.op) {
|
|
101
|
+
case '!=':
|
|
102
|
+
case '<':
|
|
103
|
+
case '<=':
|
|
104
|
+
case '=':
|
|
105
|
+
case '>':
|
|
106
|
+
case '>=':
|
|
107
|
+
case 'ILIKE':
|
|
108
|
+
case 'LIKE':
|
|
109
|
+
case 'NOT ILIKE':
|
|
110
|
+
case 'NOT LIKE':
|
|
111
|
+
return sql `${valuePosition(condition.left)} ${sql.__dangerous__rawValue(condition.op)} ${valuePosition(condition.right)}`;
|
|
112
|
+
case 'NOT IN':
|
|
113
|
+
case 'IN':
|
|
114
|
+
return any(condition);
|
|
115
|
+
case 'IS':
|
|
116
|
+
case 'IS NOT':
|
|
117
|
+
return distinctFrom(condition);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
export function distinctFrom(condition) {
|
|
121
|
+
return sql `${valuePosition(condition.left)} ${condition.op === 'IS' ? sql `IS NOT DISTINCT FROM` : sql `IS DISTINCT FROM`} ${valuePosition(condition.right)}`;
|
|
122
|
+
}
|
|
123
|
+
export function any(condition) {
|
|
124
|
+
return sql `${valuePosition(condition.left)} ${condition.op === 'IN' ? sql `= ANY` : sql `!= ANY`} (${valuePosition(condition.right)})`;
|
|
125
|
+
}
|
|
126
|
+
export function valuePosition(value) {
|
|
127
|
+
switch (value.type) {
|
|
128
|
+
case 'column':
|
|
129
|
+
return sql.ident(value.name);
|
|
130
|
+
case 'literal':
|
|
131
|
+
return sql.value(value.value);
|
|
132
|
+
case 'static':
|
|
133
|
+
throw new Error('Static parameters must be bound to a value before compiling to SQL');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
export function exists(condition, parentTable) {
|
|
137
|
+
switch (condition.op) {
|
|
138
|
+
case 'EXISTS':
|
|
139
|
+
return sql `EXISTS (${select(condition.related.subquery, undefined, correlate(parentTable, condition.related.correlation.parentField, condition.related.subquery.table, condition.related.correlation.childField))})`;
|
|
140
|
+
case 'NOT EXISTS':
|
|
141
|
+
return sql `NOT EXISTS (${select(condition.related.subquery, undefined, undefined)})`;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
export function correlate(parentTable, parentColumns, childTable, childColumns) {
|
|
145
|
+
return sql.join(zip(parentColumns, childColumns).map(([parentColumn, childColumn]) => sql `${sql.ident(parentTable)}.${sql.ident(parentColumn)} = ${sql.ident(childTable)}.${sql.ident(childColumn)}`), ' AND ');
|
|
146
|
+
}
|
|
147
|
+
function zip(a1, a2) {
|
|
148
|
+
assert(a1.length === a2.length);
|
|
149
|
+
const result = [];
|
|
150
|
+
for (let i = 0; i < a1.length; i++) {
|
|
151
|
+
result.push([a1[i], a2[i]]);
|
|
152
|
+
}
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=compiler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compiler.js","sourceRoot":"","sources":["../../../../z2s/src/compiler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SQLQuery } from '@databases/sql';
|
|
2
|
+
import baseSql from '@databases/sql';
|
|
3
|
+
export declare function formatPg(sql: SQLQuery): {
|
|
4
|
+
text: string;
|
|
5
|
+
values: unknown[];
|
|
6
|
+
};
|
|
7
|
+
export declare function formatSqlite(sql: SQLQuery): {
|
|
8
|
+
text: string;
|
|
9
|
+
values: unknown[];
|
|
10
|
+
};
|
|
11
|
+
export declare const sql: baseSql.SQL;
|
|
12
|
+
//# sourceMappingURL=sql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../../../z2s/src/sql.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAe,MAAM,gBAAgB,CAAC;AAC3D,OAAO,OAAO,MAAM,gBAAgB,CAAC;AAgBrC,wBAAgB,QAAQ,CAAC,GAAG,EAAE,QAAQ;;;EAErC;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,QAAQ;;;EAEzC;AAED,eAAO,MAAM,GAAG,aAAkB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import baseSql from '@databases/sql';
|
|
2
|
+
import { escapePostgresIdentifier, escapeSQLiteIdentifier, } from '@databases/escape-identifier';
|
|
3
|
+
const pgFormat = {
|
|
4
|
+
escapeIdentifier: str => escapePostgresIdentifier(str),
|
|
5
|
+
formatValue: (value, index) => ({ placeholder: `$${index + 1}`, value }),
|
|
6
|
+
};
|
|
7
|
+
const sqliteFormat = {
|
|
8
|
+
escapeIdentifier: str => escapeSQLiteIdentifier(str),
|
|
9
|
+
formatValue: value => ({ placeholder: '?', value }),
|
|
10
|
+
};
|
|
11
|
+
export function formatPg(sql) {
|
|
12
|
+
return sql.format(pgFormat);
|
|
13
|
+
}
|
|
14
|
+
export function formatSqlite(sql) {
|
|
15
|
+
return sql.format(sqliteFormat);
|
|
16
|
+
}
|
|
17
|
+
export const sql = baseSql.default;
|
|
18
|
+
//# sourceMappingURL=sql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql.js","sourceRoot":"","sources":["../../../../z2s/src/sql.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,gBAAgB,CAAC;AACrC,OAAO,EACL,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,8BAA8B,CAAC;AAEtC,MAAM,QAAQ,GAAiB;IAC7B,gBAAgB,EAAE,GAAG,CAAC,EAAE,CAAC,wBAAwB,CAAC,GAAG,CAAC;IACtD,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAC,WAAW,EAAE,IAAI,KAAK,GAAG,CAAC,EAAE,EAAE,KAAK,EAAC,CAAC;CACvE,CAAC;AAEF,MAAM,YAAY,GAAiB;IACjC,gBAAgB,EAAE,GAAG,CAAC,EAAE,CAAC,sBAAsB,CAAC,GAAG,CAAC;IACpD,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,EAAC,WAAW,EAAE,GAAG,EAAE,KAAK,EAAC,CAAC;CAClD,CAAC;AAEF,MAAM,UAAU,QAAQ,CAAC,GAAa;IACpC,OAAO,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAa;IACxC,OAAO,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg.d.ts","sourceRoot":"","sources":["../../../src/pg.ts"],"names":[],"mappings":"AACA,cAAc,0BAA0B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg.js","sourceRoot":"","sources":["../../../src/pg.ts"],"names":[],"mappings":"AAAA,iDAAiD;AACjD,cAAc,0BAA0B,CAAC"}
|
|
@@ -7,8 +7,8 @@ export type LoadedPermissions = {
|
|
|
7
7
|
permissions: PermissionsConfig | null;
|
|
8
8
|
hash: string | null;
|
|
9
9
|
};
|
|
10
|
-
export declare function loadPermissions(lc: LogContext, replica: StatementRunner): LoadedPermissions;
|
|
11
|
-
export declare function reloadPermissionsIfChanged(lc: LogContext, replica: StatementRunner, current: LoadedPermissions | null): {
|
|
10
|
+
export declare function loadPermissions(lc: LogContext, replica: StatementRunner, appID: string): LoadedPermissions;
|
|
11
|
+
export declare function reloadPermissionsIfChanged(lc: LogContext, replica: StatementRunner, appID: string, current: LoadedPermissions | null): {
|
|
12
12
|
permissions: LoadedPermissions;
|
|
13
13
|
changed: boolean;
|
|
14
14
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-permissions.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/auth/load-permissions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,oDAAoD,CAAC;AAC/E,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,kDAAkD,CAAC;AAE1D,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,2BAA2B,CAAC;AAExD,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,qBAAqB,CAAC;AAGzD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACtC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB,CAAC;AAEF,wBAAgB,eAAe,CAC7B,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"load-permissions.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/auth/load-permissions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,oDAAoD,CAAC;AAC/E,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,kDAAkD,CAAC;AAE1D,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,2BAA2B,CAAC;AAExD,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,qBAAqB,CAAC;AAGzD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACtC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB,CAAC;AAEF,wBAAgB,eAAe,CAC7B,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,MAAM,GACZ,iBAAiB,CA6BnB;AAED,wBAAgB,0BAA0B,CACxC,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,eAAe,EACxB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,iBAAiB,GAAG,IAAI,GAChC;IAAC,WAAW,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAC,CAQpD;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,GAAG,MAAM,CAgBnE"}
|
|
@@ -2,8 +2,8 @@ import * as v from "../../../shared/src/valita.js";
|
|
|
2
2
|
import { permissionsConfigSchema, } from "../../../zero-schema/src/compiled-permissions.js";
|
|
3
3
|
import { computeZqlSpecs } from "../db/lite-tables.js";
|
|
4
4
|
import { elide } from "../types/strings.js";
|
|
5
|
-
export function loadPermissions(lc, replica) {
|
|
6
|
-
const { permissions, hash } = replica.get(`SELECT permissions, hash FROM "
|
|
5
|
+
export function loadPermissions(lc, replica, appID) {
|
|
6
|
+
const { permissions, hash } = replica.get(`SELECT permissions, hash FROM "${appID}.permissions"`);
|
|
7
7
|
if (permissions === null) {
|
|
8
8
|
lc.warn?.(`\n\n\n` +
|
|
9
9
|
`No upstream permissions deployed.\n` +
|
|
@@ -24,17 +24,16 @@ export function loadPermissions(lc, replica) {
|
|
|
24
24
|
`This may happen if Permissions with a new internal format are ` +
|
|
25
25
|
`deployed before the supporting server has been fully rolled out.`, { cause: e });
|
|
26
26
|
}
|
|
27
|
-
lc.debug?.(`Loaded permissions (hash: ${hash})`);
|
|
28
27
|
return { permissions: parsed, hash };
|
|
29
28
|
}
|
|
30
|
-
export function reloadPermissionsIfChanged(lc, replica, current) {
|
|
29
|
+
export function reloadPermissionsIfChanged(lc, replica, appID, current) {
|
|
31
30
|
if (current === null) {
|
|
32
|
-
return { permissions: loadPermissions(lc, replica), changed: true };
|
|
31
|
+
return { permissions: loadPermissions(lc, replica, appID), changed: true };
|
|
33
32
|
}
|
|
34
|
-
const { hash } = replica.get(`SELECT hash FROM "
|
|
33
|
+
const { hash } = replica.get(`SELECT hash FROM "${appID}.permissions"`);
|
|
35
34
|
return hash === current.hash
|
|
36
35
|
? { permissions: current, changed: false }
|
|
37
|
-
: { permissions: loadPermissions(lc, replica), changed: true };
|
|
36
|
+
: { permissions: loadPermissions(lc, replica, appID), changed: true };
|
|
38
37
|
}
|
|
39
38
|
export function getSchema(lc, replica) {
|
|
40
39
|
const specs = computeZqlSpecs(lc, replica);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"load-permissions.js","sourceRoot":"","sources":["../../../../../zero-cache/src/auth/load-permissions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,+BAA+B,CAAC;AAEnD,OAAO,EACL,uBAAuB,GAExB,MAAM,kDAAkD,CAAC;AAG1D,OAAO,EAAC,eAAe,EAAC,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAC,KAAK,EAAC,MAAM,qBAAqB,CAAC;AAO1C,MAAM,UAAU,eAAe,CAC7B,EAAc,EACd,OAAwB;
|
|
1
|
+
{"version":3,"file":"load-permissions.js","sourceRoot":"","sources":["../../../../../zero-cache/src/auth/load-permissions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,+BAA+B,CAAC;AAEnD,OAAO,EACL,uBAAuB,GAExB,MAAM,kDAAkD,CAAC;AAG1D,OAAO,EAAC,eAAe,EAAC,MAAM,sBAAsB,CAAC;AAErD,OAAO,EAAC,KAAK,EAAC,MAAM,qBAAqB,CAAC;AAO1C,MAAM,UAAU,eAAe,CAC7B,EAAc,EACd,OAAwB,EACxB,KAAa;IAEb,MAAM,EAAC,WAAW,EAAE,IAAI,EAAC,GAAG,OAAO,CAAC,GAAG,CACrC,kCAAkC,KAAK,eAAe,CACvD,CAAC;IACF,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;QACzB,EAAE,CAAC,IAAI,EAAE,CACP,QAAQ;YACN,qCAAqC;YACrC,2DAA2D;YAC3D,QAAQ,CACX,CAAC;QACF,OAAO,EAAC,WAAW,EAAE,IAAI,EAAE,IAAI,EAAC,CAAC;IACnC,CAAC;IACD,IAAI,GAAG,CAAC;IACR,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC9B,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,uBAAuB,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,iEAAiE;QACjE,MAAM,IAAI,KAAK,CACb,wCAAwC;YACtC,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM;YACzC,gEAAgE;YAChE,kEAAkE,EACpE,EAAC,KAAK,EAAE,CAAC,EAAC,CACX,CAAC;IACJ,CAAC;IACD,OAAO,EAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,EAAc,EACd,OAAwB,EACxB,KAAa,EACb,OAAiC;IAEjC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,OAAO,EAAC,WAAW,EAAE,eAAe,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,IAAI,EAAC,CAAC;IAC3E,CAAC;IACD,MAAM,EAAC,IAAI,EAAC,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,eAAe,CAAC,CAAC;IACtE,OAAO,IAAI,KAAK,OAAO,CAAC,IAAI;QAC1B,CAAC,CAAC,EAAC,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAC;QACxC,CAAC,CAAC,EAAC,WAAW,EAAE,eAAe,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,IAAI,EAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,EAAc,EAAE,OAAiB;IACzD,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAC/B,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QAC9B,MAAM,EACJ,SAAS,EAAE,EAAC,IAAI,EAAE,UAAU,EAAC,EAC7B,OAAO,EAAE,OAAO,GACjB,GAAG,KAAK,CAAC;QACV,OAAO,CAAC,IAAI,EAAE,EAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAuB,CAAC,CAAC;IACnE,CAAC,CAAC,CACH,CAAC;IACF,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,+BAA+B;QAC3C,MAAM;QACN,aAAa,EAAE,EAAE,EAAE,iDAAiD;KACrE,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-authorizer.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/auth/read-authorizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,MAAM,CAAC;AAGrC,OAAO,KAAK,EAAC,GAAG,EAAY,MAAM,mCAAmC,CAAC;AACtE,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,kDAAkD,CAAC;AAGxF,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,GAAG,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AACF;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,UAAU,EACd,KAAK,EAAE,GAAG,EACV,eAAe,EAAE,iBAAiB,EAClC,QAAQ,EAAE,UAAU,GAAG,SAAS,EAChC,aAAa,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,GACxC,oBAAoB,
|
|
1
|
+
{"version":3,"file":"read-authorizer.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/auth/read-authorizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,MAAM,CAAC;AAGrC,OAAO,KAAK,EAAC,GAAG,EAAY,MAAM,mCAAmC,CAAC;AACtE,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,kDAAkD,CAAC;AAGxF,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,GAAG,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AACF;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,UAAU,EACd,KAAK,EAAE,GAAG,EACV,eAAe,EAAE,iBAAiB,EAClC,QAAQ,EAAE,UAAU,GAAG,SAAS,EAChC,aAAa,EAAE,OAAO,GAAG,IAAI,GAAG,SAAS,GACxC,oBAAoB,CAetB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,EAAE,EAAE,UAAU,EACd,KAAK,EAAE,GAAG,EACV,eAAe,EAAE,iBAAiB,EAClC,QAAQ,EAAE,UAAU,GAAG,SAAS,GAC/B,GAAG,CASL"}
|
|
@@ -14,7 +14,7 @@ export function transformAndHashQuery(lc, query, permissionRules, authData, inte
|
|
|
14
14
|
const transformed = internalQuery
|
|
15
15
|
? query // application permissions do not apply to internal queries
|
|
16
16
|
: transformQuery(lc, query, permissionRules, authData);
|
|
17
|
-
lc.debug?.(`read authorizer transformed query ${JSON.stringify(query)} to ${JSON.stringify(transformed)}
|
|
17
|
+
lc.debug?.(`read authorizer transformed query ${JSON.stringify(query)} to ${JSON.stringify(transformed)} and authData ${JSON.stringify(authData)}`);
|
|
18
18
|
return {
|
|
19
19
|
query: transformed,
|
|
20
20
|
hash: hashOfAST(transformed),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-authorizer.js","sourceRoot":"","sources":["../../../../../zero-cache/src/auth/read-authorizer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAC,SAAS,EAAC,MAAM,wCAAwC,CAAC;AAGjE,OAAO,EAAC,oBAAoB,EAAC,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAC,GAAG,EAAC,MAAM,+BAA+B,CAAC;AAOlD;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CACnC,EAAc,EACd,KAAU,EACV,eAAkC,EAClC,QAAgC,EAChC,aAAyC;IAEzC,MAAM,WAAW,GAAG,aAAa;QAC/B,CAAC,CAAC,KAAK,CAAC,2DAA2D;QACnE,CAAC,CAAC,cAAc,CAAC,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,QAAQ,CAAC,CAAC;IACzD,EAAE,CAAC,KAAK,EAAE,CACR,qCAAqC,IAAI,CAAC,SAAS,CACjD,KAAK,CACN,OAAO,IAAI,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"read-authorizer.js","sourceRoot":"","sources":["../../../../../zero-cache/src/auth/read-authorizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ export interface WriteAuthorizer {
|
|
|
11
11
|
}
|
|
12
12
|
export declare class WriteAuthorizerImpl implements WriteAuthorizer {
|
|
13
13
|
#private;
|
|
14
|
-
constructor(lc: LogContext, config: ZeroConfig, replica: Database, cgID: string);
|
|
14
|
+
constructor(lc: LogContext, config: ZeroConfig, replica: Database, appID: string, cgID: string);
|
|
15
15
|
reloadPermissions(): void;
|
|
16
16
|
canPreMutation(authData: JWTPayload | undefined, ops: Exclude<CRUDOp, UpsertOp>[]): boolean;
|
|
17
17
|
canPostMutation(authData: JWTPayload | undefined, ops: Exclude<CRUDOp, UpsertOp>[]): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write-authorizer.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/auth/write-authorizer.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,MAAM,CAAC;AAcrC,OAAO,KAAK,EACV,MAAM,EAIN,QAAQ,EACT,MAAM,oCAAoC,CAAC;AAW5C,OAAO,EAAC,QAAQ,EAAC,MAAM,2BAA2B,CAAC;AAMnD,OAAO,KAAK,EAAY,UAAU,EAAC,MAAM,0BAA0B,CAAC;AAcpE,MAAM,WAAW,eAAe;IAC9B,cAAc,CACZ,QAAQ,EAAE,UAAU,GAAG,SAAS,EAChC,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,GAC/B,OAAO,CAAC;IACX,eAAe,CACb,QAAQ,EAAE,UAAU,GAAG,SAAS,EAChC,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,GAC/B,OAAO,CAAC;IACX,iBAAiB,IAAI,IAAI,CAAC;IAC1B,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;CAC1D;AAED,qBAAa,mBAAoB,YAAW,eAAe;;
|
|
1
|
+
{"version":3,"file":"write-authorizer.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/auth/write-authorizer.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,MAAM,CAAC;AAcrC,OAAO,KAAK,EACV,MAAM,EAIN,QAAQ,EACT,MAAM,oCAAoC,CAAC;AAW5C,OAAO,EAAC,QAAQ,EAAC,MAAM,2BAA2B,CAAC;AAMnD,OAAO,KAAK,EAAY,UAAU,EAAC,MAAM,0BAA0B,CAAC;AAcpE,MAAM,WAAW,eAAe;IAC9B,cAAc,CACZ,QAAQ,EAAE,UAAU,GAAG,SAAS,EAChC,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,GAC/B,OAAO,CAAC;IACX,eAAe,CACb,QAAQ,EAAE,UAAU,GAAG,SAAS,EAChC,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,GAC/B,OAAO,CAAC;IACX,iBAAiB,IAAI,IAAI,CAAC;IAC1B,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;CAC1D;AAED,qBAAa,mBAAoB,YAAW,eAAe;;gBAevD,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,QAAQ,EACjB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM;IAuBd,iBAAiB;IASjB,cAAc,CACZ,QAAQ,EAAE,UAAU,GAAG,SAAS,EAChC,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;IAsBlC,eAAe,CACb,QAAQ,EAAE,UAAU,GAAG,SAAS,EAChC,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;IA6DlC,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE;CAsSzD"}
|
|
@@ -26,10 +26,12 @@ export class WriteAuthorizerImpl {
|
|
|
26
26
|
#tables = new Map();
|
|
27
27
|
#statementRunner;
|
|
28
28
|
#lc;
|
|
29
|
+
#appID;
|
|
29
30
|
#clientGroupID;
|
|
30
31
|
#logConfig;
|
|
31
32
|
#loadedPermissions = null;
|
|
32
|
-
constructor(lc, config, replica, cgID) {
|
|
33
|
+
constructor(lc, config, replica, appID, cgID) {
|
|
34
|
+
this.#appID = appID;
|
|
33
35
|
this.#clientGroupID = cgID;
|
|
34
36
|
this.#lc = lc.withContext('class', 'WriteAuthorizerImpl');
|
|
35
37
|
this.#logConfig = config.log;
|
|
@@ -47,7 +49,7 @@ export class WriteAuthorizerImpl {
|
|
|
47
49
|
this.reloadPermissions();
|
|
48
50
|
}
|
|
49
51
|
reloadPermissions() {
|
|
50
|
-
this.#loadedPermissions = reloadPermissionsIfChanged(this.#lc, this.#statementRunner, this.#loadedPermissions).permissions;
|
|
52
|
+
this.#loadedPermissions = reloadPermissionsIfChanged(this.#lc, this.#statementRunner, this.#appID, this.#loadedPermissions).permissions;
|
|
51
53
|
}
|
|
52
54
|
canPreMutation(authData, ops) {
|
|
53
55
|
for (const op of ops) {
|