@ahmadmoussawi/webdb 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -6
- package/dist/angular.cjs +2 -0
- package/dist/angular.cjs.map +1 -0
- package/dist/angular.d.ts +92 -0
- package/dist/angular.js +108 -0
- package/dist/angular.js.map +1 -0
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/js/catalog.c.d.ts +88 -27
- package/dist/core/js/catalog.c.d.ts.map +1 -1
- package/dist/host/api/index.d.ts +1 -0
- package/dist/host/api/index.d.ts.map +1 -1
- package/dist/host/api/live_query.d.ts +71 -0
- package/dist/host/api/live_query.d.ts.map +1 -0
- package/dist/host/api/query_builder.d.ts +20 -0
- package/dist/host/api/query_builder.d.ts.map +1 -1
- package/dist/host/api/webdb.d.ts +8 -0
- package/dist/host/api/webdb.d.ts.map +1 -1
- package/dist/host/driver/buffer_pool_driver.d.ts.map +1 -1
- package/dist/react.cjs +2 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.ts +52 -0
- package/dist/react.js +66 -0
- package/dist/react.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/vue.cjs +2 -0
- package/dist/vue.cjs.map +1 -0
- package/dist/vue.d.ts +100 -0
- package/dist/vue.js +80 -0
- package/dist/vue.js.map +1 -0
- package/dist/webdb.js +5438 -4890
- package/dist/webdb.js.map +1 -1
- package/dist/webdb.umd.cjs +2 -2
- package/dist/webdb.umd.cjs.map +1 -1
- package/package.json +37 -2
package/dist/vue.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { provide as L, shallowRef as s, ref as h, watch as m, getCurrentScope as S, onScopeDispose as _, readonly as i, inject as C } from "vue";
|
|
2
|
+
import { createLiveQuery as g } from "@ahmadmoussawi/webdb";
|
|
3
|
+
const c = Symbol("WEBDB_INSTANCE");
|
|
4
|
+
function I(e, r) {
|
|
5
|
+
return r && typeof r.provide == "function" ? r.provide(c, e) : L(c, e), e;
|
|
6
|
+
}
|
|
7
|
+
function U() {
|
|
8
|
+
const e = B();
|
|
9
|
+
if (!e)
|
|
10
|
+
throw new Error(
|
|
11
|
+
"useWebDB() found no provided WebDB instance. Call provideWebDB(db) in a parent component or on your Vue app."
|
|
12
|
+
);
|
|
13
|
+
return e;
|
|
14
|
+
}
|
|
15
|
+
function B() {
|
|
16
|
+
try {
|
|
17
|
+
return C(c, null) ?? null;
|
|
18
|
+
} catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function j(e) {
|
|
23
|
+
return !(!e || typeof e != "object" || Array.isArray(e) || "__v_isRef" in e || "value" in e || "effect" in e);
|
|
24
|
+
}
|
|
25
|
+
function N(e, r, a) {
|
|
26
|
+
let n, t;
|
|
27
|
+
j(r) ? (t = r, n = t.watch) : (n = r, t = a ?? {}, !n && t.watch && (n = t.watch));
|
|
28
|
+
const E = t.db ? null : B(), W = t.db ?? E, f = s(t.initialData), d = h(!0), p = s(null), b = h(null), v = s(null), u = g(e, {
|
|
29
|
+
...t,
|
|
30
|
+
db: W
|
|
31
|
+
}), w = u.subscribe((o) => {
|
|
32
|
+
f.value = o.data, d.value = o.isLoading, p.value = o.error, b.value = o.lastUpdated, v.value = o.lastEvent;
|
|
33
|
+
});
|
|
34
|
+
let l = null;
|
|
35
|
+
n && (l = m(
|
|
36
|
+
n,
|
|
37
|
+
() => {
|
|
38
|
+
u.refresh();
|
|
39
|
+
},
|
|
40
|
+
{ deep: t.deep }
|
|
41
|
+
));
|
|
42
|
+
let D = !1;
|
|
43
|
+
const y = () => {
|
|
44
|
+
if (!D) {
|
|
45
|
+
if (D = !0, l) {
|
|
46
|
+
try {
|
|
47
|
+
l();
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
50
|
+
l = null;
|
|
51
|
+
}
|
|
52
|
+
w(), u.destroy();
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
return S() && _(y), {
|
|
56
|
+
data: i(f),
|
|
57
|
+
isLoading: i(d),
|
|
58
|
+
error: i(p),
|
|
59
|
+
lastUpdated: i(b),
|
|
60
|
+
lastEvent: i(v),
|
|
61
|
+
refresh: () => u.refresh(),
|
|
62
|
+
stop: y
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function R(e, r, a, n = {}) {
|
|
66
|
+
const { data: t } = N(e, r, {
|
|
67
|
+
...n,
|
|
68
|
+
initialData: n.initialData ?? a
|
|
69
|
+
});
|
|
70
|
+
return t;
|
|
71
|
+
}
|
|
72
|
+
export {
|
|
73
|
+
c as WEBDB_INJECTION_KEY,
|
|
74
|
+
I as provideWebDB,
|
|
75
|
+
N as useLiveQuery,
|
|
76
|
+
R as useLiveQueryData,
|
|
77
|
+
B as useOptionalWebDB,
|
|
78
|
+
U as useWebDB
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=vue.js.map
|
package/dist/vue.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vue.js","sources":["../src/vue/index.ts"],"sourcesContent":["/// <reference path=\"./peer-types.d.ts\" />\nimport {\n ref,\n shallowRef,\n readonly,\n watch,\n getCurrentScope,\n onScopeDispose,\n provide,\n inject,\n type Ref,\n type ShallowRef,\n type WatchSource,\n type InjectionKey,\n} from 'vue';\nimport {\n createLiveQuery,\n type WebDB,\n type DbRow,\n type TableChangeEvent,\n type LiveQueryFn,\n type LiveQueryOptions,\n} from '@ahmadmoussawi/webdb';\n\n/**\n * Vue InjectionKey for providing and injecting a WebDB instance across a Vue component tree.\n */\nexport const WEBDB_INJECTION_KEY: InjectionKey<WebDB> = Symbol('WEBDB_INSTANCE') as InjectionKey<WebDB>;\n\n/**\n * Provides a WebDB instance either inside a Vue component's `setup()` or on a Vue `App` instance.\n *\n * @example\n * ```ts\n * // In main.ts:\n * const app = createApp(App);\n * provideWebDB(db, app);\n *\n * // Or inside a root component <script setup>:\n * provideWebDB(db);\n * ```\n */\nexport function provideWebDB(\n db: WebDB,\n app?: { provide: (key: any, value: any) => any },\n): WebDB {\n if (app && typeof app.provide === 'function') {\n app.provide(WEBDB_INJECTION_KEY, db);\n } else {\n provide(WEBDB_INJECTION_KEY, db);\n }\n return db;\n}\n\n/**\n * Injects the nearest provided WebDB instance in a Vue component or composable.\n * Throws if no WebDB instance was provided via `provideWebDB(db)`.\n */\nexport function useWebDB(): WebDB {\n const db = useOptionalWebDB();\n if (!db) {\n throw new Error(\n 'useWebDB() found no provided WebDB instance. Call provideWebDB(db) in a parent component or on your Vue app.',\n );\n }\n return db;\n}\n\n/**\n * Injects the nearest provided WebDB instance, or returns `null` if none is provided.\n */\nexport function useOptionalWebDB(): WebDB | null {\n try {\n return inject(WEBDB_INJECTION_KEY, null as unknown as WebDB) ?? null;\n } catch {\n return null;\n }\n}\n\nexport interface VueLiveQueryOptions<T> extends LiveQueryOptions<T> {\n /**\n * Optional Vue reactive watch source(s) (`Ref`, `ComputedRef`, getter, or array of sources)\n * that should trigger a query re-execution when mutated.\n */\n watch?: WatchSource | WatchSource[];\n /**\n * Whether to enable deep watching on `watch` sources (default: false).\n */\n deep?: boolean;\n}\n\nexport interface UseVueLiveQueryReturn<T> {\n /** Reactive ref containing the latest query result (`initialData` or `undefined` while loading) */\n readonly data: Readonly<ShallowRef<T | undefined>>;\n /** Reactive ref indicating whether the initial query is currently loading */\n readonly isLoading: Readonly<Ref<boolean>>;\n /** Reactive ref containing the latest query error, or `null` */\n readonly error: Readonly<ShallowRef<Error | null>>;\n /** Reactive ref containing the timestamp of the last successful query execution */\n readonly lastUpdated: Readonly<Ref<number | null>>;\n /** Reactive ref containing the last table change event that triggered a refresh */\n readonly lastEvent: Readonly<ShallowRef<TableChangeEvent | null>>;\n /** Manually forces a re-execution of the query */\n refresh: () => Promise<T | undefined>;\n /** Stops all database and reactive watchers for this live query */\n stop: () => void;\n}\n\nfunction isLiveQueryOptionsObject<T>(\n val: unknown,\n): val is VueLiveQueryOptions<T> {\n if (!val || typeof val !== 'object' || Array.isArray(val)) return false;\n // Vue Ref / ComputedRef have `.value` or `__v_isRef`\n if ('__v_isRef' in val || 'value' in val || 'effect' in val) return false;\n return true;\n}\n\n/**\n * Vue 3 composable that executes a WebDB query and automatically updates reactive `Ref`s whenever:\n * 1. Any referenced WebDB tables (including JOINs & subqueries) are modified locally or across tabs, OR\n * 2. Any watched Vue `Ref` / `ComputedRef` / getter passed in `deps` or `options.watch` changes.\n *\n * Automatically cleans up subscriptions when the enclosing Vue component or `effectScope` is disposed.\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { ref } from 'vue';\n * import { useLiveQuery } from '@ahmadmoussawi/webdb/vue';\n *\n * const filterStatus = ref('active');\n * const { data: todos, isLoading, error } = useLiveQuery(\n * () => db.from('todos').where('status', '=', filterStatus.value).orderBy('id', 'desc'),\n * [filterStatus],\n * { initialData: [] }\n * );\n * </script>\n * ```\n */\nexport function useLiveQuery<T = DbRow[]>(\n queryFn: LiveQueryFn<T>,\n depsOrOptions?: WatchSource | WatchSource[] | VueLiveQueryOptions<T>,\n maybeOptions?: VueLiveQueryOptions<T>,\n): UseVueLiveQueryReturn<T> {\n let watchSources: WatchSource | WatchSource[] | undefined;\n let options: VueLiveQueryOptions<T>;\n\n if (isLiveQueryOptionsObject<T>(depsOrOptions)) {\n options = depsOrOptions;\n watchSources = options.watch;\n } else {\n watchSources = depsOrOptions as WatchSource | WatchSource[] | undefined;\n options = maybeOptions ?? {};\n if (!watchSources && options.watch) {\n watchSources = options.watch;\n }\n }\n\n const injectedDb = options.db ? null : useOptionalWebDB();\n const resolvedDb = options.db ?? injectedDb;\n\n const data = shallowRef<T | undefined>(options.initialData);\n const isLoading = ref<boolean>(true);\n const error = shallowRef<Error | null>(null);\n const lastUpdated = ref<number | null>(null);\n const lastEvent = shallowRef<TableChangeEvent | null>(null);\n\n const controller = createLiveQuery<T>(queryFn, {\n ...options,\n db: resolvedDb,\n });\n\n const unsubController = controller.subscribe((state) => {\n data.value = state.data;\n isLoading.value = state.isLoading;\n error.value = state.error;\n lastUpdated.value = state.lastUpdated;\n lastEvent.value = state.lastEvent;\n });\n\n let stopWatch: (() => void) | null = null;\n if (watchSources) {\n stopWatch = watch(\n watchSources,\n () => {\n void controller.refresh();\n },\n { deep: options.deep },\n );\n }\n\n let isStopped = false;\n const stop = () => {\n if (isStopped) return;\n isStopped = true;\n if (stopWatch) {\n try {\n stopWatch();\n } catch {}\n stopWatch = null;\n }\n unsubController();\n controller.destroy();\n };\n\n if (getCurrentScope()) {\n onScopeDispose(stop);\n }\n\n return {\n data: readonly(data) as Readonly<ShallowRef<T | undefined>>,\n isLoading: readonly(isLoading) as Readonly<Ref<boolean>>,\n error: readonly(error) as Readonly<ShallowRef<Error | null>>,\n lastUpdated: readonly(lastUpdated) as Readonly<Ref<number | null>>,\n lastEvent: readonly(lastEvent) as Readonly<ShallowRef<TableChangeEvent | null>>,\n refresh: () => controller.refresh(),\n stop,\n };\n}\n\n/**\n * Concise Vue 3 composable that returns a single readonly `Ref<T | undefined>` containing\n * the live query result directly (or `defaultValue` while loading).\n *\n * @example\n * ```vue\n * <script setup lang=\"ts\">\n * import { useLiveQueryData } from '@ahmadmoussawi/webdb/vue';\n *\n * const todos = useLiveQueryData(\n * () => db.from('todos').orderBy('id', 'desc'),\n * [],\n * []\n * );\n * </script>\n * ```\n */\nexport function useLiveQueryData<T = DbRow[]>(\n queryFn: LiveQueryFn<T>,\n deps?: WatchSource | WatchSource[],\n defaultValue?: T,\n options: VueLiveQueryOptions<T> = {},\n): Readonly<ShallowRef<T | undefined>> {\n const { data } = useLiveQuery<T>(queryFn, deps, {\n ...options,\n initialData: options.initialData ?? defaultValue,\n });\n return data;\n}\n\n"],"names":["WEBDB_INJECTION_KEY","provideWebDB","db","app","provide","useWebDB","useOptionalWebDB","inject","isLiveQueryOptionsObject","val","useLiveQuery","queryFn","depsOrOptions","maybeOptions","watchSources","options","injectedDb","resolvedDb","data","shallowRef","isLoading","ref","error","lastUpdated","lastEvent","controller","createLiveQuery","unsubController","state","stopWatch","watch","isStopped","stop","getCurrentScope","onScopeDispose","readonly","useLiveQueryData","deps","defaultValue"],"mappings":";;AA2BO,MAAMA,IAA2C,OAAO,gBAAgB;AAexE,SAASC,EACdC,GACAC,GACO;AACP,SAAIA,KAAO,OAAOA,EAAI,WAAY,aAChCA,EAAI,QAAQH,GAAqBE,CAAE,IAEnCE,EAAQJ,GAAqBE,CAAE,GAE1BA;AACT;AAMO,SAASG,IAAkB;AAChC,QAAMH,IAAKI,EAAA;AACX,MAAI,CAACJ;AACH,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAGJ,SAAOA;AACT;AAKO,SAASI,IAAiC;AAC/C,MAAI;AACF,WAAOC,EAAOP,GAAqB,IAAwB,KAAK;AAAA,EAClE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AA+BA,SAASQ,EACPC,GAC+B;AAG/B,SAFI,GAACA,KAAO,OAAOA,KAAQ,YAAY,MAAM,QAAQA,CAAG,KAEpD,eAAeA,KAAO,WAAWA,KAAO,YAAYA;AAE1D;AAwBO,SAASC,EACdC,GACAC,GACAC,GAC0B;AAC1B,MAAIC,GACAC;AAEJ,EAAIP,EAA4BI,CAAa,KAC3CG,IAAUH,GACVE,IAAeC,EAAQ,UAEvBD,IAAeF,GACfG,IAAUF,KAAgB,CAAA,GACtB,CAACC,KAAgBC,EAAQ,UAC3BD,IAAeC,EAAQ;AAI3B,QAAMC,IAAaD,EAAQ,KAAK,OAAOT,EAAA,GACjCW,IAAaF,EAAQ,MAAMC,GAE3BE,IAAOC,EAA0BJ,EAAQ,WAAW,GACpDK,IAAYC,EAAa,EAAI,GAC7BC,IAAQH,EAAyB,IAAI,GACrCI,IAAcF,EAAmB,IAAI,GACrCG,IAAYL,EAAoC,IAAI,GAEpDM,IAAaC,EAAmBf,GAAS;AAAA,IAC7C,GAAGI;AAAA,IACH,IAAIE;AAAA,EAAA,CACL,GAEKU,IAAkBF,EAAW,UAAU,CAACG,MAAU;AACtD,IAAAV,EAAK,QAAQU,EAAM,MACnBR,EAAU,QAAQQ,EAAM,WACxBN,EAAM,QAAQM,EAAM,OACpBL,EAAY,QAAQK,EAAM,aAC1BJ,EAAU,QAAQI,EAAM;AAAA,EAC1B,CAAC;AAED,MAAIC,IAAiC;AACrC,EAAIf,MACFe,IAAYC;AAAA,IACVhB;AAAA,IACA,MAAM;AACJ,MAAKW,EAAW,QAAA;AAAA,IAClB;AAAA,IACA,EAAE,MAAMV,EAAQ,KAAA;AAAA,EAAK;AAIzB,MAAIgB,IAAY;AAChB,QAAMC,IAAO,MAAM;AACjB,QAAI,CAAAD,GAEJ;AAAA,UADAA,IAAY,IACRF,GAAW;AACb,YAAI;AACF,UAAAA,EAAA;AAAA,QACF,QAAQ;AAAA,QAAC;AACT,QAAAA,IAAY;AAAA,MACd;AACA,MAAAF,EAAA,GACAF,EAAW,QAAA;AAAA;AAAA,EACb;AAEA,SAAIQ,OACFC,EAAeF,CAAI,GAGd;AAAA,IACL,MAAMG,EAASjB,CAAI;AAAA,IACnB,WAAWiB,EAASf,CAAS;AAAA,IAC7B,OAAOe,EAASb,CAAK;AAAA,IACrB,aAAaa,EAASZ,CAAW;AAAA,IACjC,WAAWY,EAASX,CAAS;AAAA,IAC7B,SAAS,MAAMC,EAAW,QAAA;AAAA,IAC1B,MAAAO;AAAA,EAAA;AAEJ;AAmBO,SAASI,EACdzB,GACA0B,GACAC,GACAvB,IAAkC,CAAA,GACG;AACrC,QAAM,EAAE,MAAAG,EAAA,IAASR,EAAgBC,GAAS0B,GAAM;AAAA,IAC9C,GAAGtB;AAAA,IACH,aAAaA,EAAQ,eAAeuB;AAAA,EAAA,CACrC;AACD,SAAOpB;AACT;"}
|