@spooky-sync/client-solid 0.0.1-canary.5 → 0.0.1-canary.50
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/dist/index.cjs +53 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +21 -21
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +21 -21
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +54 -55
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
- package/skills/sp00ky-solid/SKILL.md +264 -0
- package/skills/sp00ky-solid/references/file-hooks.md +112 -0
- package/src/cache/index.ts +1 -1
- package/src/cache/surrealdb-wasm-factory.ts +4 -1
- package/src/index.ts +59 -52
- package/src/lib/{SpookyProvider.ts → Sp00kyProvider.ts} +9 -7
- package/src/lib/context.ts +3 -3
- package/src/lib/models.ts +1 -1
- package/src/lib/use-download-file.ts +2 -2
- package/src/lib/use-file-upload.ts +2 -1
- package/src/lib/use-query.ts +14 -14
- package/src/types/index.ts +3 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AuthService, BucketHandle, RunOptions,
|
|
1
|
+
import { AuthService, BucketHandle, RunOptions, Sp00kyClient, Sp00kyConfig, Sp00kyQueryResultPromise, UpdateOptions } from "@spooky-sync/core";
|
|
2
2
|
import { RecordId, RecordId as RecordId$1, Surreal, Uuid } from "surrealdb";
|
|
3
3
|
import { Accessor, JSX } from "solid-js";
|
|
4
4
|
import { GenericModel, GenericSchema, SchemaStructure } from "@spooky/query-builder";
|
|
@@ -37,12 +37,12 @@ type InferRelationshipsFromConst<S extends SchemaStructure$1, Schema extends Gen
|
|
|
37
37
|
cardinality: Rel['cardinality'];
|
|
38
38
|
} } };
|
|
39
39
|
type Prettify<T> = { [K in keyof T]: T[K] } & {};
|
|
40
|
-
type SyncedDbConfig<S extends SchemaStructure$1> = Prettify<
|
|
40
|
+
type SyncedDbConfig<S extends SchemaStructure$1> = Prettify<Sp00kyConfig<S>>;
|
|
41
41
|
//#endregion
|
|
42
42
|
//#region src/lib/use-query.d.ts
|
|
43
43
|
type QueryArg<S extends SchemaStructure$1, TableName extends TableNames$1<S>, T extends {
|
|
44
44
|
columns: Record<string, ColumnSchema>;
|
|
45
|
-
}, RelatedFields extends Record<string, any>, IsOne extends boolean> = FinalQuery<S, TableName, T, RelatedFields, IsOne,
|
|
45
|
+
}, RelatedFields extends Record<string, any>, IsOne extends boolean> = FinalQuery<S, TableName, T, RelatedFields, IsOne, Sp00kyQueryResultPromise> | (() => FinalQuery<S, TableName, T, RelatedFields, IsOne, Sp00kyQueryResultPromise> | null | undefined);
|
|
46
46
|
type QueryOptions = {
|
|
47
47
|
enabled?: () => boolean;
|
|
48
48
|
};
|
|
@@ -89,16 +89,16 @@ declare function useDownloadFile<S extends SchemaStructure$1>(bucketName: Bucket
|
|
|
89
89
|
declare function useDownloadFile<S extends SchemaStructure$1>(db: SyncedDb<S>, bucketName: BucketNames<S>, path: Accessor<string | null | undefined>, options?: UseDownloadFileOptions): UseDownloadFileResult;
|
|
90
90
|
//# sourceMappingURL=use-download-file.d.ts.map
|
|
91
91
|
//#endregion
|
|
92
|
-
//#region src/lib/
|
|
93
|
-
interface
|
|
92
|
+
//#region src/lib/Sp00kyProvider.d.ts
|
|
93
|
+
interface Sp00kyProviderProps<S extends SchemaStructure> {
|
|
94
94
|
config: SyncedDbConfig<S>;
|
|
95
95
|
fallback?: JSX.Element;
|
|
96
96
|
onError?: (error: Error) => void;
|
|
97
97
|
onReady?: (db: SyncedDb<S>) => void;
|
|
98
98
|
children: JSX.Element;
|
|
99
99
|
}
|
|
100
|
-
declare function
|
|
101
|
-
//# sourceMappingURL=
|
|
100
|
+
declare function Sp00kyProvider<S extends SchemaStructure>(props: Sp00kyProviderProps<S>): JSX.Element;
|
|
101
|
+
//# sourceMappingURL=Sp00kyProvider.d.ts.map
|
|
102
102
|
//#endregion
|
|
103
103
|
//#region src/lib/context.d.ts
|
|
104
104
|
declare function useDb<S extends SchemaStructure>(): SyncedDb<S>;
|
|
@@ -106,13 +106,13 @@ declare function useDb<S extends SchemaStructure>(): SyncedDb<S>;
|
|
|
106
106
|
|
|
107
107
|
//#endregion
|
|
108
108
|
//#region src/index.d.ts
|
|
109
|
-
type RelationshipField<Schema extends SchemaStructure$1, TableName extends TableNames
|
|
110
|
-
type RelatedFieldsTableScoped<Schema extends SchemaStructure$1, TableName extends TableNames
|
|
109
|
+
type RelationshipField<Schema extends SchemaStructure$1, TableName extends TableNames<Schema>, Field extends RelationshipFieldsFromSchema<Schema, TableName>> = GetRelationship<Schema, TableName, Field>;
|
|
110
|
+
type RelatedFieldsTableScoped<Schema extends SchemaStructure$1, TableName extends TableNames<Schema>, RelatedFields extends RelationshipFieldsFromSchema<Schema, TableName> = RelationshipFieldsFromSchema<Schema, TableName>> = { [K in RelatedFields]: {
|
|
111
111
|
to: RelationshipField<Schema, TableName, K>['to'];
|
|
112
112
|
relatedFields: RelatedFieldsMap;
|
|
113
113
|
cardinality: RelationshipField<Schema, TableName, K>['cardinality'];
|
|
114
114
|
} };
|
|
115
|
-
type InferModel<Schema extends SchemaStructure$1, TableName extends TableNames
|
|
115
|
+
type InferModel<Schema extends SchemaStructure$1, TableName extends TableNames<Schema>, RelatedFields extends RelatedFieldsTableScoped<Schema, TableName>> = QueryResult<Schema, TableName, RelatedFields, true>;
|
|
116
116
|
type WithRelated<Field extends string, RelatedFields extends RelatedFieldsMap = {}> = { [K in Field]: Omit<RelatedFieldMapEntry, 'relatedFields'> & {
|
|
117
117
|
relatedFields: RelatedFields;
|
|
118
118
|
} };
|
|
@@ -122,17 +122,17 @@ type WithRelatedMany<Field extends string, RelatedFields extends RelatedFieldsMa
|
|
|
122
122
|
cardinality: 'many';
|
|
123
123
|
} };
|
|
124
124
|
/**
|
|
125
|
-
* SyncedDb - A thin wrapper around
|
|
126
|
-
* Delegates all logic to the underlying
|
|
125
|
+
* SyncedDb - A thin wrapper around sp00ky-ts for Solid.js integration
|
|
126
|
+
* Delegates all logic to the underlying sp00ky-ts instance
|
|
127
127
|
*/
|
|
128
128
|
declare class SyncedDb<S extends SchemaStructure$1> {
|
|
129
129
|
private config;
|
|
130
|
-
private
|
|
130
|
+
private sp00ky;
|
|
131
131
|
private _initialized;
|
|
132
132
|
constructor(config: SyncedDbConfig<S>);
|
|
133
|
-
|
|
133
|
+
getSp00ky(): Sp00kyClient<S>;
|
|
134
134
|
/**
|
|
135
|
-
* Initialize the
|
|
135
|
+
* Initialize the sp00ky-ts instance
|
|
136
136
|
*/
|
|
137
137
|
init(): Promise<void>;
|
|
138
138
|
/**
|
|
@@ -142,15 +142,15 @@ declare class SyncedDb<S extends SchemaStructure$1> {
|
|
|
142
142
|
/**
|
|
143
143
|
* Update an existing record in the database
|
|
144
144
|
*/
|
|
145
|
-
update<TName extends TableNames
|
|
145
|
+
update<TName extends TableNames<S>>(tableName: TName, recordId: string, payload: Partial<TableModel<GetTable<S, TName>>>, options?: UpdateOptions): Promise<void>;
|
|
146
146
|
/**
|
|
147
147
|
* Delete an existing record in the database
|
|
148
148
|
*/
|
|
149
|
-
delete<TName extends TableNames
|
|
149
|
+
delete<TName extends TableNames<S>>(tableName: TName, selector: string | InnerQuery<GetTable<S, TName>, boolean>): Promise<void>;
|
|
150
150
|
/**
|
|
151
151
|
* Query data from the database
|
|
152
152
|
*/
|
|
153
|
-
query<TName extends TableNames
|
|
153
|
+
query<TName extends TableNames<S>>(table: TName): QueryBuilder<S, TName, Sp00kyQueryResultPromise, {}, false>;
|
|
154
154
|
/**
|
|
155
155
|
* Run a backend operation
|
|
156
156
|
*/
|
|
@@ -175,11 +175,11 @@ declare class SyncedDb<S extends SchemaStructure$1> {
|
|
|
175
175
|
/**
|
|
176
176
|
* Access the remote database service directly
|
|
177
177
|
*/
|
|
178
|
-
get remote():
|
|
178
|
+
get remote(): Sp00kyClient<S>['remoteClient'];
|
|
179
179
|
/**
|
|
180
180
|
* Access the local database service directly
|
|
181
181
|
*/
|
|
182
|
-
get local():
|
|
182
|
+
get local(): Sp00kyClient<S>['localClient'];
|
|
183
183
|
/**
|
|
184
184
|
* Access the auth service
|
|
185
185
|
*/
|
|
@@ -190,5 +190,5 @@ declare class SyncedDb<S extends SchemaStructure$1> {
|
|
|
190
190
|
getBucketConfig(name: string): BucketDefinitionSchema | undefined;
|
|
191
191
|
}
|
|
192
192
|
//#endregion
|
|
193
|
-
export { CacheStrategy, type FileUploadResult, type GenericModel, type GenericSchema, type GetCardinality, type GetTable, InferModel, type InferRelatedModelFromMetadata, InferRelationshipsFromConst, InferSchemaFromConst, type Model, type ModelPayload, ProvisionOptions, type QueryInfo, type QueryModifier, type QueryModifierBuilder, type QueryResult, RecordId, RelatedFieldsTableScoped, type RelationshipDefinition, RelationshipField, type RelationshipsMetadata,
|
|
193
|
+
export { CacheStrategy, type FileUploadResult, type GenericModel, type GenericSchema, type GetCardinality, type GetTable, InferModel, type InferRelatedModelFromMetadata, InferRelationshipsFromConst, InferSchemaFromConst, type Model, type ModelPayload, ProvisionOptions, type QueryInfo, type QueryModifier, type QueryModifierBuilder, type QueryResult, RecordId, RelatedFieldsTableScoped, type RelationshipDefinition, RelationshipField, type RelationshipsMetadata, Sp00kyProvider, type Sp00kyProviderProps, SyncedDb, SyncedDbConfig, type TableModel, type TableNames, type UseDownloadFileOptions, type UseDownloadFileResult, Uuid, WithRelated, WithRelatedMany, useDb, useDownloadFile, useFileUpload, useQuery };
|
|
194
194
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/lib/models.ts","../../../src/types/index.ts","../../../src/lib/use-query.ts","../../../src/lib/use-file-upload.ts","../../../src/lib/use-download-file.ts","../../../src/lib/
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/lib/models.ts","../../../src/types/index.ts","../../../src/lib/use-query.ts","../../../src/lib/use-file-upload.ts","../../../src/lib/use-download-file.ts","../../../src/lib/Sp00kyProvider.ts","../../../src/lib/context.ts","../../../src/index.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Sp00kyClient, fileToUint8Array } from "@spooky-sync/core";
|
|
2
2
|
import { RecordId, Uuid } from "surrealdb";
|
|
3
3
|
import { createComponent, createContext, createEffect, createMemo, createSignal, mergeProps, onCleanup, onMount, useContext } from "solid-js";
|
|
4
4
|
|
|
5
5
|
//#region src/lib/context.ts
|
|
6
|
-
const
|
|
6
|
+
const Sp00kyContext = createContext();
|
|
7
7
|
function useDb() {
|
|
8
|
-
const db = useContext(
|
|
9
|
-
if (!db) throw new Error("useDb must be used within a <
|
|
8
|
+
const db = useContext(Sp00kyContext);
|
|
9
|
+
if (!db) throw new Error("useDb must be used within a <Sp00kyProvider>. Wrap your app in <Sp00kyProvider config={...}>.");
|
|
10
10
|
return db;
|
|
11
11
|
}
|
|
12
12
|
|
|
@@ -21,8 +21,8 @@ function useQuery(dbOrQuery, queryOrOptions, maybeOptions) {
|
|
|
21
21
|
finalQuery = queryOrOptions;
|
|
22
22
|
options = maybeOptions;
|
|
23
23
|
} else {
|
|
24
|
-
const contextDb = useContext(
|
|
25
|
-
if (!contextDb) throw new Error("useQuery: No db argument provided and no
|
|
24
|
+
const contextDb = useContext(Sp00kyContext);
|
|
25
|
+
if (!contextDb) throw new Error("useQuery: No db argument provided and no Sp00kyContext found. Either pass a SyncedDb instance or wrap your app in <Sp00kyProvider>.");
|
|
26
26
|
db = contextDb;
|
|
27
27
|
finalQuery = dbOrQuery;
|
|
28
28
|
options = queryOrOptions;
|
|
@@ -32,15 +32,15 @@ function useQuery(dbOrQuery, queryOrOptions, maybeOptions) {
|
|
|
32
32
|
const [isFetched, setIsFetched] = createSignal(false);
|
|
33
33
|
const [unsubscribe, setUnsubscribe] = createSignal(void 0);
|
|
34
34
|
let prevQueryString;
|
|
35
|
-
const
|
|
35
|
+
const sp00ky = db.getSp00ky();
|
|
36
36
|
const initQuery = async (query) => {
|
|
37
37
|
const { hash } = await query.run();
|
|
38
38
|
setError(void 0);
|
|
39
39
|
let isFirstCall = true;
|
|
40
|
-
const unsub = await
|
|
41
|
-
const
|
|
42
|
-
setData(() =>
|
|
43
|
-
const hasData = query.isOne ?
|
|
40
|
+
const unsub = await sp00ky.subscribe(hash, (e) => {
|
|
41
|
+
const queryData = query.isOne ? e[0] : e;
|
|
42
|
+
setData(() => queryData);
|
|
43
|
+
const hasData = query.isOne ? queryData !== null && queryData !== void 0 : e.length > 0;
|
|
44
44
|
if (!isFirstCall || hasData) setIsFetched(true);
|
|
45
45
|
isFirstCall = false;
|
|
46
46
|
}, { immediate: true });
|
|
@@ -94,7 +94,7 @@ function useFileUpload(dbOrBucketName, maybeBucketName) {
|
|
|
94
94
|
const validate = (file) => {
|
|
95
95
|
const config = db.getBucketConfig(bucketName);
|
|
96
96
|
if (!config) return;
|
|
97
|
-
if (config.maxSize
|
|
97
|
+
if (config.maxSize !== null && config.maxSize !== void 0 && file.size > config.maxSize) {
|
|
98
98
|
const maxMB = (config.maxSize / (1024 * 1024)).toFixed(1);
|
|
99
99
|
throw new Error(`File exceeds maximum size of ${maxMB} MB.`);
|
|
100
100
|
}
|
|
@@ -203,9 +203,8 @@ function useDownloadFile(dbOrBucketName, bucketNameOrPath, pathOrOptions, maybeO
|
|
|
203
203
|
const [error, setError] = createSignal(null);
|
|
204
204
|
let currentKey = null;
|
|
205
205
|
let privateUrl = null;
|
|
206
|
-
let refetchTrigger;
|
|
207
206
|
const [refetchSignal, setRefetchSignal] = createSignal(0);
|
|
208
|
-
refetchTrigger = () => setRefetchSignal((n) => n + 1);
|
|
207
|
+
const refetchTrigger = () => setRefetchSignal((n) => n + 1);
|
|
209
208
|
async function doDownload(key, filePath) {
|
|
210
209
|
if (useCache) {
|
|
211
210
|
const cached = downloadCache.get(key);
|
|
@@ -325,8 +324,8 @@ function useDownloadFile(dbOrBucketName, bucketNameOrPath, pathOrOptions, maybeO
|
|
|
325
324
|
}
|
|
326
325
|
|
|
327
326
|
//#endregion
|
|
328
|
-
//#region src/lib/
|
|
329
|
-
function
|
|
327
|
+
//#region src/lib/Sp00kyProvider.ts
|
|
328
|
+
function Sp00kyProvider(props) {
|
|
330
329
|
const merged = mergeProps({ fallback: void 0 }, props);
|
|
331
330
|
const [db, setDb] = createSignal(void 0);
|
|
332
331
|
onMount(async () => {
|
|
@@ -338,13 +337,13 @@ function SpookyProvider(props) {
|
|
|
338
337
|
} catch (e) {
|
|
339
338
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
340
339
|
if (merged.onError) merged.onError(error);
|
|
341
|
-
else console.error("
|
|
340
|
+
else console.error("Sp00kyProvider: Failed to initialize database", error);
|
|
342
341
|
}
|
|
343
342
|
});
|
|
344
343
|
return createMemo(() => {
|
|
345
344
|
const instance = db();
|
|
346
345
|
if (!instance) return merged.fallback;
|
|
347
|
-
return createComponent(
|
|
346
|
+
return createComponent(Sp00kyContext.Provider, {
|
|
348
347
|
value: instance,
|
|
349
348
|
get children() {
|
|
350
349
|
return merged.children;
|
|
@@ -356,69 +355,69 @@ function SpookyProvider(props) {
|
|
|
356
355
|
//#endregion
|
|
357
356
|
//#region src/index.ts
|
|
358
357
|
/**
|
|
359
|
-
* SyncedDb - A thin wrapper around
|
|
360
|
-
* Delegates all logic to the underlying
|
|
358
|
+
* SyncedDb - A thin wrapper around sp00ky-ts for Solid.js integration
|
|
359
|
+
* Delegates all logic to the underlying sp00ky-ts instance
|
|
361
360
|
*/
|
|
362
361
|
var SyncedDb = class {
|
|
363
362
|
constructor(config) {
|
|
364
|
-
this.
|
|
363
|
+
this.sp00ky = null;
|
|
365
364
|
this._initialized = false;
|
|
366
365
|
this.config = config;
|
|
367
366
|
}
|
|
368
|
-
|
|
369
|
-
if (!this.
|
|
370
|
-
return this.
|
|
367
|
+
getSp00ky() {
|
|
368
|
+
if (!this.sp00ky) throw new Error("SyncedDb not initialized");
|
|
369
|
+
return this.sp00ky;
|
|
371
370
|
}
|
|
372
371
|
/**
|
|
373
|
-
* Initialize the
|
|
372
|
+
* Initialize the sp00ky-ts instance
|
|
374
373
|
*/
|
|
375
374
|
async init() {
|
|
376
375
|
if (this._initialized) return;
|
|
377
|
-
this.
|
|
378
|
-
await this.
|
|
376
|
+
this.sp00ky = new Sp00kyClient(this.config);
|
|
377
|
+
await this.sp00ky.init();
|
|
379
378
|
this._initialized = true;
|
|
380
379
|
}
|
|
381
380
|
/**
|
|
382
381
|
* Create a new record in the database
|
|
383
382
|
*/
|
|
384
383
|
async create(id, payload) {
|
|
385
|
-
if (!this.
|
|
386
|
-
await this.
|
|
384
|
+
if (!this.sp00ky) throw new Error("SyncedDb not initialized");
|
|
385
|
+
await this.sp00ky.create(id, payload);
|
|
387
386
|
}
|
|
388
387
|
/**
|
|
389
388
|
* Update an existing record in the database
|
|
390
389
|
*/
|
|
391
390
|
async update(tableName, recordId, payload, options) {
|
|
392
|
-
if (!this.
|
|
393
|
-
await this.
|
|
391
|
+
if (!this.sp00ky) throw new Error("SyncedDb not initialized");
|
|
392
|
+
await this.sp00ky.update(tableName, recordId, payload, options);
|
|
394
393
|
}
|
|
395
394
|
/**
|
|
396
395
|
* Delete an existing record in the database
|
|
397
396
|
*/
|
|
398
397
|
async delete(tableName, selector) {
|
|
399
|
-
if (!this.
|
|
398
|
+
if (!this.sp00ky) throw new Error("SyncedDb not initialized");
|
|
400
399
|
if (typeof selector !== "string") throw new Error("Only string ID selectors are supported currently with core");
|
|
401
|
-
await this.
|
|
400
|
+
await this.sp00ky.delete(tableName, selector);
|
|
402
401
|
}
|
|
403
402
|
/**
|
|
404
403
|
* Query data from the database
|
|
405
404
|
*/
|
|
406
405
|
query(table) {
|
|
407
|
-
if (!this.
|
|
408
|
-
return this.
|
|
406
|
+
if (!this.sp00ky) throw new Error("SyncedDb not initialized");
|
|
407
|
+
return this.sp00ky.query(table, {});
|
|
409
408
|
}
|
|
410
409
|
/**
|
|
411
410
|
* Run a backend operation
|
|
412
411
|
*/
|
|
413
412
|
async run(backend, path, payload, options) {
|
|
414
|
-
if (!this.
|
|
415
|
-
await this.
|
|
413
|
+
if (!this.sp00ky) throw new Error("SyncedDb not initialized");
|
|
414
|
+
await this.sp00ky.run(backend, path, payload, options);
|
|
416
415
|
}
|
|
417
416
|
/**
|
|
418
417
|
* Authenticate with the database
|
|
419
418
|
*/
|
|
420
419
|
async authenticate(token) {
|
|
421
|
-
await this.
|
|
420
|
+
await this.sp00ky?.authenticate(token);
|
|
422
421
|
return new RecordId("user", "me");
|
|
423
422
|
}
|
|
424
423
|
/**
|
|
@@ -432,48 +431,48 @@ var SyncedDb = class {
|
|
|
432
431
|
* Sign out, clear session and local storage
|
|
433
432
|
*/
|
|
434
433
|
async signOut() {
|
|
435
|
-
if (!this.
|
|
436
|
-
await this.
|
|
434
|
+
if (!this.sp00ky) throw new Error("SyncedDb not initialized");
|
|
435
|
+
await this.sp00ky.auth.signOut();
|
|
437
436
|
}
|
|
438
437
|
/**
|
|
439
438
|
* Execute a function with direct access to the remote database connection
|
|
440
439
|
*/
|
|
441
440
|
async useRemote(fn) {
|
|
442
|
-
if (!this.
|
|
443
|
-
return await this.
|
|
441
|
+
if (!this.sp00ky) throw new Error("SyncedDb not initialized");
|
|
442
|
+
return await this.sp00ky.useRemote(fn);
|
|
444
443
|
}
|
|
445
444
|
/**
|
|
446
445
|
* Access the remote database service directly
|
|
447
446
|
*/
|
|
448
447
|
get remote() {
|
|
449
|
-
if (!this.
|
|
450
|
-
return this.
|
|
448
|
+
if (!this.sp00ky) throw new Error("SyncedDb not initialized");
|
|
449
|
+
return this.sp00ky.remoteClient;
|
|
451
450
|
}
|
|
452
451
|
/**
|
|
453
452
|
* Access the local database service directly
|
|
454
453
|
*/
|
|
455
454
|
get local() {
|
|
456
|
-
if (!this.
|
|
457
|
-
return this.
|
|
455
|
+
if (!this.sp00ky) throw new Error("SyncedDb not initialized");
|
|
456
|
+
return this.sp00ky.localClient;
|
|
458
457
|
}
|
|
459
458
|
/**
|
|
460
459
|
* Access the auth service
|
|
461
460
|
*/
|
|
462
461
|
get auth() {
|
|
463
|
-
if (!this.
|
|
464
|
-
return this.
|
|
462
|
+
if (!this.sp00ky) throw new Error("SyncedDb not initialized");
|
|
463
|
+
return this.sp00ky.auth;
|
|
465
464
|
}
|
|
466
465
|
get pendingMutationCount() {
|
|
467
|
-
if (!this.
|
|
468
|
-
return this.
|
|
466
|
+
if (!this.sp00ky) throw new Error("SyncedDb not initialized");
|
|
467
|
+
return this.sp00ky.pendingMutationCount;
|
|
469
468
|
}
|
|
470
469
|
subscribeToPendingMutations(cb) {
|
|
471
|
-
if (!this.
|
|
472
|
-
return this.
|
|
470
|
+
if (!this.sp00ky) throw new Error("SyncedDb not initialized");
|
|
471
|
+
return this.sp00ky.subscribeToPendingMutations(cb);
|
|
473
472
|
}
|
|
474
473
|
bucket(name) {
|
|
475
|
-
if (!this.
|
|
476
|
-
return this.
|
|
474
|
+
if (!this.sp00ky) throw new Error("SyncedDb not initialized");
|
|
475
|
+
return this.sp00ky.bucket(name);
|
|
477
476
|
}
|
|
478
477
|
getBucketConfig(name) {
|
|
479
478
|
return this.config.schema.buckets?.find((b) => b.name === name);
|
|
@@ -481,5 +480,5 @@ var SyncedDb = class {
|
|
|
481
480
|
};
|
|
482
481
|
|
|
483
482
|
//#endregion
|
|
484
|
-
export { RecordId,
|
|
483
|
+
export { RecordId, Sp00kyProvider, SyncedDb, Uuid, useDb, useDownloadFile, useFileUpload, useQuery };
|
|
485
484
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/lib/context.ts","../src/lib/use-query.ts","../src/lib/use-file-upload.ts","../src/lib/use-download-file.ts","../src/lib/SpookyProvider.ts","../src/index.ts"],"sourcesContent":["import { createContext, useContext } from 'solid-js';\nimport type { SchemaStructure } from '@spooky/query-builder';\nimport type { SyncedDb } from '../index';\n\nexport const SpookyContext = createContext<SyncedDb<any> | undefined>();\n\nexport function useDb<S extends SchemaStructure>(): SyncedDb<S> {\n const db = useContext(SpookyContext);\n if (!db) {\n throw new Error('useDb must be used within a <SpookyProvider>. Wrap your app in <SpookyProvider config={...}>.');\n }\n return db as SyncedDb<S>;\n}\n","import {\n ColumnSchema,\n FinalQuery,\n SchemaStructure,\n TableNames,\n QueryResult,\n} from '@spooky-sync/query-builder';\nimport { createEffect, createSignal, onCleanup, useContext } from 'solid-js';\nimport { SyncedDb } from '..';\nimport { SpookyQueryResultPromise } from '@spooky-sync/core';\nimport { SpookyContext } from './context';\n\ntype QueryArg<\n S extends SchemaStructure,\n TableName extends TableNames<S>,\n T extends { columns: Record<string, ColumnSchema> },\n RelatedFields extends Record<string, any>,\n IsOne extends boolean,\n> =\n | FinalQuery<S, TableName, T, RelatedFields, IsOne, SpookyQueryResultPromise>\n | (() =>\n | FinalQuery<S, TableName, T, RelatedFields, IsOne, SpookyQueryResultPromise>\n | null\n | undefined);\n\ntype QueryOptions = { enabled?: () => boolean };\n\n// Overload: context-based (no explicit db)\nexport function useQuery<\n S extends SchemaStructure,\n TableName extends TableNames<S>,\n T extends { columns: Record<string, ColumnSchema> },\n RelatedFields extends Record<string, any>,\n IsOne extends boolean,\n TData = QueryResult<S, TableName, RelatedFields, IsOne> | null,\n>(\n finalQuery: QueryArg<S, TableName, T, RelatedFields, IsOne>,\n options?: QueryOptions,\n): { data: () => TData | undefined; error: () => Error | undefined; isLoading: () => boolean };\n\n// Overload: explicit db (backward-compatible)\nexport function useQuery<\n S extends SchemaStructure,\n TableName extends TableNames<S>,\n T extends { columns: Record<string, ColumnSchema> },\n RelatedFields extends Record<string, any>,\n IsOne extends boolean,\n TData = QueryResult<S, TableName, RelatedFields, IsOne> | null,\n>(\n db: SyncedDb<S>,\n finalQuery: QueryArg<S, TableName, T, RelatedFields, IsOne>,\n options?: QueryOptions,\n): { data: () => TData | undefined; error: () => Error | undefined; isLoading: () => boolean };\n\n// Implementation\nexport function useQuery<\n S extends SchemaStructure,\n TableName extends TableNames<S>,\n T extends {\n columns: Record<string, ColumnSchema>;\n },\n RelatedFields extends Record<string, any>,\n IsOne extends boolean,\n TData = QueryResult<S, TableName, RelatedFields, IsOne> | null,\n>(\n dbOrQuery:\n | SyncedDb<S>\n | QueryArg<S, TableName, T, RelatedFields, IsOne>,\n queryOrOptions?:\n | QueryArg<S, TableName, T, RelatedFields, IsOne>\n | QueryOptions,\n maybeOptions?: QueryOptions,\n) {\n let db: SyncedDb<S>;\n let finalQuery: QueryArg<S, TableName, T, RelatedFields, IsOne>;\n let options: QueryOptions | undefined;\n\n if (dbOrQuery instanceof SyncedDb) {\n // Explicit db overload: useQuery(db, query, options?)\n db = dbOrQuery;\n finalQuery = queryOrOptions as QueryArg<S, TableName, T, RelatedFields, IsOne>;\n options = maybeOptions;\n } else {\n // Context-based overload: useQuery(query, options?)\n const contextDb = useContext(SpookyContext);\n if (!contextDb) {\n throw new Error(\n 'useQuery: No db argument provided and no SpookyContext found. ' +\n 'Either pass a SyncedDb instance or wrap your app in <SpookyProvider>.'\n );\n }\n db = contextDb as SyncedDb<S>;\n finalQuery = dbOrQuery;\n options = queryOrOptions as QueryOptions | undefined;\n }\n\n const [data, setData] = createSignal<TData | undefined>(undefined);\n const [error, setError] = createSignal<Error | undefined>(undefined);\n const [isFetched, setIsFetched] = createSignal(false);\n const [unsubscribe, setUnsubscribe] = createSignal<(() => void) | undefined>(undefined);\n let prevQueryString: string | undefined;\n\n const spooky = db.getSpooky();\n\n const initQuery = async (\n query: FinalQuery<S, TableName, T, RelatedFields, IsOne, SpookyQueryResultPromise>\n ) => {\n const { hash } = await query.run();\n setError(undefined);\n\n let isFirstCall = true;\n const unsub = await spooky.subscribe(\n hash,\n (e) => {\n const data = (query.isOne ? e[0] : e) as TData;\n setData(() => data);\n // The first (immediate) callback with no data likely means the local DB\n // hasn't synced yet — don't mark as fetched so UI shows loading state\n const hasData = query.isOne ? data != null : (e as any[]).length > 0;\n if (!isFirstCall || hasData) {\n setIsFetched(true);\n }\n isFirstCall = false;\n },\n { immediate: true }\n );\n\n setUnsubscribe(() => unsub);\n };\n\n createEffect(() => {\n const enabled = options?.enabled?.() ?? true;\n\n // If disabled, clear error and don't run query\n if (!enabled) {\n setError(undefined);\n return;\n }\n\n // Init Query\n const query = typeof finalQuery === 'function' ? finalQuery() : finalQuery;\n if (!query) {\n return;\n }\n\n // Prevent re-running if query hasn't changed\n const queryString = JSON.stringify(query);\n if (queryString === prevQueryString) {\n return;\n }\n prevQueryString = queryString;\n\n // Reset fetched state when query changes\n setIsFetched(false);\n initQuery(query);\n\n // Cleanup\n onCleanup(() => {\n unsubscribe()?.();\n });\n });\n\n const isLoading = () => {\n return !isFetched() && error() === undefined;\n };\n\n return {\n data,\n error,\n isLoading,\n };\n}\n","import { createSignal, onCleanup } from 'solid-js';\nimport type { SchemaStructure, BucketNames } from '@spooky-sync/query-builder';\nimport { fileToUint8Array } from '@spooky-sync/core';\nimport type { SyncedDb } from '../index';\nimport { useDb } from './context';\n\nexport interface FileUploadResult {\n isUploading: () => boolean;\n error: () => Error | null;\n clearError: () => void;\n upload: (path: string, file: File | Blob) => Promise<void>;\n download: (path: string) => Promise<string | null>;\n remove: (path: string) => Promise<void>;\n exists: (path: string) => Promise<boolean>;\n}\n\nexport function useFileUpload<S extends SchemaStructure>(\n bucketName: BucketNames<S>,\n): FileUploadResult;\nexport function useFileUpload<S extends SchemaStructure>(\n db: SyncedDb<S>,\n bucketName: BucketNames<S>,\n): FileUploadResult;\nexport function useFileUpload<S extends SchemaStructure>(\n dbOrBucketName: SyncedDb<S> | BucketNames<S>,\n maybeBucketName?: BucketNames<S>,\n): FileUploadResult {\n let db: SyncedDb<S>;\n let bucketName: BucketNames<S>;\n\n if (typeof dbOrBucketName === 'string') {\n db = useDb<S>();\n bucketName = dbOrBucketName as BucketNames<S>;\n } else {\n db = dbOrBucketName as SyncedDb<S>;\n bucketName = maybeBucketName!;\n }\n\n const [isUploading, setIsUploading] = createSignal(false);\n const [error, setError] = createSignal<Error | null>(null);\n\n const objectUrls: string[] = [];\n onCleanup(() => {\n for (const url of objectUrls) {\n URL.revokeObjectURL(url);\n }\n });\n\n const clearError = () => setError(null);\n\n const validate = (file: File | Blob): void => {\n const config = db.getBucketConfig(bucketName as string);\n if (!config) return;\n\n if (config.maxSize != null && file.size > config.maxSize) {\n const maxMB = (config.maxSize / (1024 * 1024)).toFixed(1);\n throw new Error(`File exceeds maximum size of ${maxMB} MB.`);\n }\n\n if (config.allowedExtensions && config.allowedExtensions.length > 0) {\n const fileName = (file as File).name;\n if (fileName) {\n const ext = fileName.split('.').pop()?.toLowerCase();\n if (!ext || !config.allowedExtensions.includes(ext)) {\n throw new Error(\n `File type not allowed. Accepted: ${config.allowedExtensions.join(', ')}.`\n );\n }\n }\n }\n };\n\n const upload = async (path: string, file: File | Blob): Promise<void> => {\n setError(null);\n try {\n validate(file);\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n return;\n }\n\n setIsUploading(true);\n try {\n const bytes = await fileToUint8Array(file);\n await db.bucket(bucketName).put(path, bytes);\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n } finally {\n setIsUploading(false);\n }\n };\n\n const download = async (path: string): Promise<string | null> => {\n setError(null);\n try {\n const content = await db.bucket(bucketName).get(path);\n if (!content) return null;\n const objectUrl = URL.createObjectURL(new Blob([content as BlobPart]));\n objectUrls.push(objectUrl);\n return objectUrl;\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n return null;\n }\n };\n\n const remove = async (path: string): Promise<void> => {\n setError(null);\n try {\n await db.bucket(bucketName).delete(path);\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n }\n };\n\n const exists = async (path: string): Promise<boolean> => {\n setError(null);\n try {\n return await db.bucket(bucketName).exists(path);\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n return false;\n }\n };\n\n return {\n isUploading,\n error,\n clearError,\n upload,\n download,\n remove,\n exists,\n };\n}\n","import { createSignal, createEffect, onCleanup, type Accessor } from 'solid-js';\nimport type { SchemaStructure, BucketNames } from '@spooky-sync/query-builder';\nimport type { SyncedDb } from '../index';\nimport { useDb } from './context';\n\nexport interface UseDownloadFileOptions {\n cache?: boolean;\n}\n\nexport interface UseDownloadFileResult {\n url: Accessor<string | null>;\n isLoading: Accessor<boolean>;\n error: Accessor<Error | null>;\n refetch: () => void;\n}\n\ninterface CacheEntry {\n url: string;\n refCount: number;\n}\n\nconst downloadCache = new Map<string, CacheEntry>();\nconst inflightRequests = new Map<string, Promise<string | null>>();\n\nfunction cacheKey(bucket: string, path: string): string {\n return `${bucket}:${path}`;\n}\n\nfunction releaseEntry(key: string): void {\n const entry = downloadCache.get(key);\n if (!entry) return;\n entry.refCount--;\n if (entry.refCount <= 0) {\n URL.revokeObjectURL(entry.url);\n downloadCache.delete(key);\n }\n}\n\nexport function useDownloadFile<S extends SchemaStructure>(\n bucketName: BucketNames<S>,\n path: Accessor<string | null | undefined>,\n options?: UseDownloadFileOptions,\n): UseDownloadFileResult;\nexport function useDownloadFile<S extends SchemaStructure>(\n db: SyncedDb<S>,\n bucketName: BucketNames<S>,\n path: Accessor<string | null | undefined>,\n options?: UseDownloadFileOptions,\n): UseDownloadFileResult;\nexport function useDownloadFile<S extends SchemaStructure>(\n dbOrBucketName: SyncedDb<S> | BucketNames<S>,\n bucketNameOrPath?: BucketNames<S> | Accessor<string | null | undefined>,\n pathOrOptions?: Accessor<string | null | undefined> | UseDownloadFileOptions,\n maybeOptions?: UseDownloadFileOptions,\n): UseDownloadFileResult {\n let db: SyncedDb<S>;\n let bucketName: BucketNames<S>;\n let path: Accessor<string | null | undefined>;\n let options: UseDownloadFileOptions;\n\n if (typeof dbOrBucketName === 'string') {\n db = useDb<S>();\n bucketName = dbOrBucketName as BucketNames<S>;\n path = bucketNameOrPath as Accessor<string | null | undefined>;\n options = (pathOrOptions as UseDownloadFileOptions) ?? {};\n } else {\n db = dbOrBucketName as SyncedDb<S>;\n bucketName = bucketNameOrPath as BucketNames<S>;\n path = pathOrOptions as Accessor<string | null | undefined>;\n options = maybeOptions ?? {};\n }\n\n const useCache = options.cache !== false;\n\n const [url, setUrl] = createSignal<string | null>(null);\n const [isLoading, setIsLoading] = createSignal(false);\n const [error, setError] = createSignal<Error | null>(null);\n\n let currentKey: string | null = null;\n let privateUrl: string | null = null;\n let refetchTrigger: () => void;\n const [refetchSignal, setRefetchSignal] = createSignal(0);\n refetchTrigger = () => setRefetchSignal((n) => n + 1);\n\n async function doDownload(key: string, filePath: string): Promise<string | null> {\n if (useCache) {\n // Check cache\n const cached = downloadCache.get(key);\n if (cached) {\n cached.refCount++;\n currentKey = key;\n return cached.url;\n }\n\n // Check inflight\n const inflight = inflightRequests.get(key);\n if (inflight) {\n const result = await inflight;\n if (result) {\n const entry = downloadCache.get(key);\n if (entry) {\n entry.refCount++;\n currentKey = key;\n }\n }\n return result;\n }\n\n // Start new download\n const promise = (async () => {\n const content = await db.bucket(bucketName).get(filePath);\n if (!content) return null;\n const objectUrl = URL.createObjectURL(new Blob([content as BlobPart]));\n downloadCache.set(key, { url: objectUrl, refCount: 1 });\n return objectUrl;\n })();\n\n inflightRequests.set(key, promise);\n try {\n const result = await promise;\n currentKey = key;\n return result;\n } finally {\n inflightRequests.delete(key);\n }\n } else {\n // No caching — private URL per instance\n const content = await db.bucket(bucketName).get(filePath);\n if (!content) return null;\n const objectUrl = URL.createObjectURL(new Blob([content as BlobPart]));\n privateUrl = objectUrl;\n return objectUrl;\n }\n }\n\n function releaseCurrentEntry() {\n if (useCache && currentKey) {\n releaseEntry(currentKey);\n currentKey = null;\n }\n if (!useCache && privateUrl) {\n URL.revokeObjectURL(privateUrl);\n privateUrl = null;\n }\n }\n\n createEffect(() => {\n const filePath = path();\n // Subscribe to refetch signal so effect re-runs\n refetchSignal();\n\n // Release previous entry\n releaseCurrentEntry();\n\n if (!filePath) {\n setUrl(null);\n setIsLoading(false);\n setError(null);\n return;\n }\n\n const key = cacheKey(bucketName as string, filePath);\n\n // Synchronous cache hit\n if (useCache) {\n const cached = downloadCache.get(key);\n if (cached) {\n cached.refCount++;\n currentKey = key;\n setUrl(cached.url);\n setIsLoading(false);\n setError(null);\n return;\n }\n }\n\n let cancelled = false;\n setIsLoading(true);\n setError(null);\n\n doDownload(key, filePath).then(\n (result) => {\n if (!cancelled) {\n setUrl(result);\n setIsLoading(false);\n }\n },\n (err) => {\n if (!cancelled) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsLoading(false);\n }\n },\n );\n\n onCleanup(() => {\n cancelled = true;\n });\n });\n\n onCleanup(() => {\n releaseCurrentEntry();\n });\n\n const refetch = () => {\n // Evict current entry from cache before re-triggering\n if (useCache && currentKey) {\n const entry = downloadCache.get(currentKey);\n if (entry) {\n URL.revokeObjectURL(entry.url);\n downloadCache.delete(currentKey);\n }\n currentKey = null;\n }\n refetchTrigger();\n };\n\n return { url, isLoading, error, refetch };\n}\n","import { createSignal, onMount, createComponent, createMemo, JSX, mergeProps } from 'solid-js';\nimport type { SchemaStructure } from '@spooky/query-builder';\nimport type { SyncedDbConfig } from '../types';\nimport { SyncedDb } from '../index';\nimport { SpookyContext } from './context';\n\nexport interface SpookyProviderProps<S extends SchemaStructure> {\n config: SyncedDbConfig<S>;\n fallback?: JSX.Element;\n onError?: (error: Error) => void;\n onReady?: (db: SyncedDb<S>) => void;\n children: JSX.Element;\n}\n\nexport function SpookyProvider<S extends SchemaStructure>(\n props: SpookyProviderProps<S>\n): JSX.Element {\n const merged = mergeProps(\n {\n fallback: undefined as JSX.Element | undefined,\n },\n props\n );\n\n const [db, setDb] = createSignal<SyncedDb<S> | undefined>(undefined);\n\n onMount(async () => {\n try {\n const instance = new SyncedDb<S>(merged.config);\n await instance.init();\n setDb(() => instance);\n merged.onReady?.(instance);\n } catch (e) {\n const error = e instanceof Error ? e : new Error(String(e));\n if (merged.onError) {\n merged.onError(error);\n } else {\n console.error('SpookyProvider: Failed to initialize database', error);\n }\n }\n });\n\n const content = createMemo(() => {\n const instance = db();\n if (!instance) return merged.fallback;\n return createComponent(SpookyContext.Provider, {\n value: instance,\n get children() {\n return merged.children;\n },\n });\n });\n\n return content as unknown as JSX.Element;\n}\n","import type { SyncedDbConfig } from './types';\nimport {\n SpookyClient,\n AuthService,\n BucketHandle,\n type SpookyQueryResultPromise,\n UpdateOptions,\n RunOptions,\n} from '@spooky-sync/core';\n\nimport {\n GetTable,\n QueryBuilder,\n SchemaStructure,\n TableModel,\n TableNames,\n QueryResult,\n RelatedFieldsMap,\n RelationshipFieldsFromSchema,\n GetRelationship,\n RelatedFieldMapEntry,\n InnerQuery,\n BackendNames,\n BackendRoutes,\n RoutePayload,\n BucketNames,\n BucketDefinitionSchema,\n} from '@spooky-sync/query-builder';\n\nimport { RecordId, Uuid, Surreal } from 'surrealdb';\nexport { RecordId, Uuid };\nexport type { Model, GenericModel, GenericSchema, ModelPayload } from './lib/models';\nexport { useQuery } from './lib/use-query';\nexport { useFileUpload, type FileUploadResult } from './lib/use-file-upload';\nexport { useDownloadFile, type UseDownloadFileOptions, type UseDownloadFileResult } from './lib/use-download-file';\nexport { SpookyProvider, type SpookyProviderProps } from './lib/SpookyProvider';\nexport { useDb } from './lib/context';\n\n// export { AuthEventTypes } from \"@spooky-sync/core\"; // TODO: Verify if AuthEventTypes exists in core\nexport type {};\n\n// Re-export query builder types for convenience\nexport type {\n QueryModifier,\n QueryModifierBuilder,\n QueryInfo,\n RelationshipsMetadata,\n RelationshipDefinition,\n InferRelatedModelFromMetadata,\n GetCardinality,\n GetTable,\n TableModel,\n TableNames,\n QueryResult,\n} from '@spooky-sync/query-builder';\n\nexport type RelationshipField<\n Schema extends SchemaStructure,\n TableName extends TableNames<Schema>,\n Field extends RelationshipFieldsFromSchema<Schema, TableName>,\n> = GetRelationship<Schema, TableName, Field>;\n\nexport type RelatedFieldsTableScoped<\n Schema extends SchemaStructure,\n TableName extends TableNames<Schema>,\n RelatedFields extends RelationshipFieldsFromSchema<Schema, TableName> =\n RelationshipFieldsFromSchema<Schema, TableName>,\n> = {\n [K in RelatedFields]: {\n to: RelationshipField<Schema, TableName, K>['to'];\n relatedFields: RelatedFieldsMap;\n cardinality: RelationshipField<Schema, TableName, K>['cardinality'];\n };\n};\n\nexport type InferModel<\n Schema extends SchemaStructure,\n TableName extends TableNames<Schema>,\n RelatedFields extends RelatedFieldsTableScoped<Schema, TableName>,\n> = QueryResult<Schema, TableName, RelatedFields, true>;\n\nexport type WithRelated<Field extends string, RelatedFields extends RelatedFieldsMap = {}> = {\n [K in Field]: Omit<RelatedFieldMapEntry, 'relatedFields'> & {\n relatedFields: RelatedFields;\n };\n};\n\nexport type WithRelatedMany<Field extends string, RelatedFields extends RelatedFieldsMap = {}> = {\n [K in Field]: {\n to: Field;\n relatedFields: RelatedFields;\n cardinality: 'many';\n };\n};\n\n/**\n * SyncedDb - A thin wrapper around spooky-ts for Solid.js integration\n * Delegates all logic to the underlying spooky-ts instance\n */\nexport class SyncedDb<S extends SchemaStructure> {\n private config: SyncedDbConfig<S>;\n private spooky: SpookyClient<S> | null = null;\n private _initialized = false;\n\n constructor(config: SyncedDbConfig<S>) {\n this.config = config;\n }\n\n public getSpooky(): SpookyClient<S> {\n if (!this.spooky) throw new Error('SyncedDb not initialized');\n return this.spooky;\n }\n\n /**\n * Initialize the spooky-ts instance\n */\n async init(): Promise<void> {\n if (this._initialized) return;\n this.spooky = new SpookyClient<S>(this.config);\n await this.spooky.init();\n this._initialized = true;\n }\n\n /**\n * Create a new record in the database\n */\n async create(id: string, payload: Record<string, unknown>): Promise<void> {\n if (!this.spooky) throw new Error('SyncedDb not initialized');\n await this.spooky.create(id, payload as Record<string, unknown>);\n }\n\n /**\n * Update an existing record in the database\n */\n async update<TName extends TableNames<S>>(\n tableName: TName,\n recordId: string,\n payload: Partial<TableModel<GetTable<S, TName>>>,\n options?: UpdateOptions\n ): Promise<void> {\n if (!this.spooky) throw new Error('SyncedDb not initialized');\n await this.spooky.update(\n tableName as string,\n recordId,\n payload as Record<string, unknown>,\n options\n );\n }\n\n /**\n * Delete an existing record in the database\n */\n async delete<TName extends TableNames<S>>(\n tableName: TName,\n selector: string | InnerQuery<GetTable<S, TName>, boolean>\n ): Promise<void> {\n if (!this.spooky) throw new Error('SyncedDb not initialized');\n if (typeof selector !== 'string')\n throw new Error('Only string ID selectors are supported currently with core');\n await this.spooky.delete(tableName as string, selector);\n }\n\n /**\n * Query data from the database\n */\n public query<TName extends TableNames<S>>(\n table: TName\n ): QueryBuilder<S, TName, SpookyQueryResultPromise, {}, false> {\n if (!this.spooky) throw new Error('SyncedDb not initialized');\n return this.spooky.query(table, {});\n }\n\n /**\n * Run a backend operation\n */\n public async run<\n B extends BackendNames<S>,\n R extends BackendRoutes<S, B>,\n >(\n backend: B,\n path: R,\n payload: RoutePayload<S, B, R>,\n options?: RunOptions,\n ): Promise<void> {\n if (!this.spooky) throw new Error('SyncedDb not initialized');\n await this.spooky.run(backend, path, payload, options);\n }\n\n /**\n * Authenticate with the database\n */\n public async authenticate(token: string): Promise<RecordId<string>> {\n const result = await this.spooky?.authenticate(token);\n // SpookyClient.authenticate returns whatever remote.authenticate returns (boolean or token usually?)\n // Wait, checked SpookyClient: return this.remote.getClient().authenticate(token);\n // SurrealDB authenticate returns void? or token?\n // Assuming void or token.\n return new RecordId('user', 'me'); // Placeholder or actual?\n }\n\n /**\n * Deauthenticate from the database\n * @deprecated Use signOut() instead\n */\n public async deauthenticate(): Promise<void> {\n await this.signOut();\n }\n\n /**\n * Sign out, clear session and local storage\n */\n public async signOut(): Promise<void> {\n if (!this.spooky) throw new Error('SyncedDb not initialized');\n await this.spooky.auth.signOut();\n }\n\n /**\n * Execute a function with direct access to the remote database connection\n */\n public async useRemote<T>(fn: (db: Surreal) => T | Promise<T>): Promise<T> {\n if (!this.spooky) throw new Error('SyncedDb not initialized');\n return await this.spooky.useRemote(fn);\n }\n /**\n * Access the remote database service directly\n */\n get remote(): SpookyClient<S>['remoteClient'] {\n if (!this.spooky) throw new Error('SyncedDb not initialized');\n return this.spooky.remoteClient;\n }\n\n /**\n * Access the local database service directly\n */\n get local(): SpookyClient<S>['localClient'] {\n if (!this.spooky) throw new Error('SyncedDb not initialized');\n return this.spooky.localClient;\n }\n\n /**\n * Access the auth service\n */\n get auth(): AuthService<S> {\n if (!this.spooky) throw new Error('SyncedDb not initialized');\n return this.spooky.auth;\n }\n\n get pendingMutationCount(): number {\n if (!this.spooky) throw new Error('SyncedDb not initialized');\n return this.spooky.pendingMutationCount;\n }\n\n subscribeToPendingMutations(cb: (count: number) => void): () => void {\n if (!this.spooky) throw new Error('SyncedDb not initialized');\n return this.spooky.subscribeToPendingMutations(cb);\n }\n\n bucket<B extends BucketNames<S>>(name: B): BucketHandle {\n if (!this.spooky) throw new Error('SyncedDb not initialized');\n return this.spooky.bucket(name);\n }\n\n getBucketConfig(name: string): BucketDefinitionSchema | undefined {\n return this.config.schema.buckets?.find((b) => b.name === name);\n }\n}\n\nexport * from './types';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/lib/context.ts","../src/lib/use-query.ts","../src/lib/use-file-upload.ts","../src/lib/use-download-file.ts","../src/lib/Sp00kyProvider.ts","../src/index.ts"],"sourcesContent":["import { createContext, useContext } from 'solid-js';\nimport type { SchemaStructure } from '@spooky/query-builder';\nimport type { SyncedDb } from '../index';\n\nexport const Sp00kyContext = createContext<SyncedDb<any> | undefined>();\n\nexport function useDb<S extends SchemaStructure>(): SyncedDb<S> {\n const db = useContext(Sp00kyContext);\n if (!db) {\n throw new Error('useDb must be used within a <Sp00kyProvider>. Wrap your app in <Sp00kyProvider config={...}>.');\n }\n return db as SyncedDb<S>;\n}\n","import type {\n ColumnSchema,\n FinalQuery,\n SchemaStructure,\n TableNames,\n QueryResult,\n} from '@spooky-sync/query-builder';\nimport { createEffect, createSignal, onCleanup, useContext } from 'solid-js';\nimport { SyncedDb } from '..';\nimport type { Sp00kyQueryResultPromise } from '@spooky-sync/core';\nimport { Sp00kyContext } from './context';\n\ntype QueryArg<\n S extends SchemaStructure,\n TableName extends TableNames<S>,\n T extends { columns: Record<string, ColumnSchema> },\n RelatedFields extends Record<string, any>,\n IsOne extends boolean,\n> =\n | FinalQuery<S, TableName, T, RelatedFields, IsOne, Sp00kyQueryResultPromise>\n | (() =>\n | FinalQuery<S, TableName, T, RelatedFields, IsOne, Sp00kyQueryResultPromise>\n | null\n | undefined);\n\ntype QueryOptions = { enabled?: () => boolean };\n\n// Overload: context-based (no explicit db)\nexport function useQuery<\n S extends SchemaStructure,\n TableName extends TableNames<S>,\n T extends { columns: Record<string, ColumnSchema> },\n RelatedFields extends Record<string, any>,\n IsOne extends boolean,\n TData = QueryResult<S, TableName, RelatedFields, IsOne> | null,\n>(\n finalQuery: QueryArg<S, TableName, T, RelatedFields, IsOne>,\n options?: QueryOptions,\n): { data: () => TData | undefined; error: () => Error | undefined; isLoading: () => boolean };\n\n// Overload: explicit db (backward-compatible)\nexport function useQuery<\n S extends SchemaStructure,\n TableName extends TableNames<S>,\n T extends { columns: Record<string, ColumnSchema> },\n RelatedFields extends Record<string, any>,\n IsOne extends boolean,\n TData = QueryResult<S, TableName, RelatedFields, IsOne> | null,\n>(\n db: SyncedDb<S>,\n finalQuery: QueryArg<S, TableName, T, RelatedFields, IsOne>,\n options?: QueryOptions,\n): { data: () => TData | undefined; error: () => Error | undefined; isLoading: () => boolean };\n\n// Implementation\nexport function useQuery<\n S extends SchemaStructure,\n TableName extends TableNames<S>,\n T extends {\n columns: Record<string, ColumnSchema>;\n },\n RelatedFields extends Record<string, any>,\n IsOne extends boolean,\n TData = QueryResult<S, TableName, RelatedFields, IsOne> | null,\n>(\n dbOrQuery:\n | SyncedDb<S>\n | QueryArg<S, TableName, T, RelatedFields, IsOne>,\n queryOrOptions?:\n | QueryArg<S, TableName, T, RelatedFields, IsOne>\n | QueryOptions,\n maybeOptions?: QueryOptions,\n) {\n let db: SyncedDb<S>;\n let finalQuery: QueryArg<S, TableName, T, RelatedFields, IsOne>;\n let options: QueryOptions | undefined;\n\n if (dbOrQuery instanceof SyncedDb) {\n // Explicit db overload: useQuery(db, query, options?)\n db = dbOrQuery;\n finalQuery = queryOrOptions as QueryArg<S, TableName, T, RelatedFields, IsOne>;\n options = maybeOptions;\n } else {\n // Context-based overload: useQuery(query, options?)\n const contextDb = useContext(Sp00kyContext);\n if (!contextDb) {\n throw new Error(\n 'useQuery: No db argument provided and no Sp00kyContext found. ' +\n 'Either pass a SyncedDb instance or wrap your app in <Sp00kyProvider>.'\n );\n }\n db = contextDb as SyncedDb<S>;\n finalQuery = dbOrQuery;\n options = queryOrOptions as QueryOptions | undefined;\n }\n\n const [data, setData] = createSignal<TData | undefined>(undefined);\n const [error, setError] = createSignal<Error | undefined>(undefined);\n const [isFetched, setIsFetched] = createSignal(false);\n const [unsubscribe, setUnsubscribe] = createSignal<(() => void) | undefined>(undefined);\n let prevQueryString: string | undefined;\n\n const sp00ky = db.getSp00ky();\n\n const initQuery = async (\n query: FinalQuery<S, TableName, T, RelatedFields, IsOne, Sp00kyQueryResultPromise>\n ) => {\n const { hash } = await query.run();\n setError(undefined);\n\n let isFirstCall = true;\n const unsub = await sp00ky.subscribe(\n hash,\n (e) => {\n const queryData = (query.isOne ? e[0] : e) as TData;\n setData(() => queryData);\n // The first (immediate) callback with no data likely means the local DB\n // hasn't synced yet — don't mark as fetched so UI shows loading state\n const hasData = query.isOne ? queryData !== null && queryData !== undefined : (e as any[]).length > 0;\n if (!isFirstCall || hasData) {\n setIsFetched(true);\n }\n isFirstCall = false;\n },\n { immediate: true }\n );\n\n setUnsubscribe(() => unsub);\n };\n\n createEffect(() => {\n const enabled = options?.enabled?.() ?? true;\n\n // If disabled, clear error and don't run query\n if (!enabled) {\n setError(undefined);\n return;\n }\n\n // Init Query\n const query = typeof finalQuery === 'function' ? finalQuery() : finalQuery;\n if (!query) {\n return;\n }\n\n // Prevent re-running if query hasn't changed\n const queryString = JSON.stringify(query);\n if (queryString === prevQueryString) {\n return;\n }\n prevQueryString = queryString;\n\n // Reset fetched state when query changes\n setIsFetched(false);\n initQuery(query);\n\n // Cleanup\n onCleanup(() => {\n unsubscribe()?.();\n });\n });\n\n const isLoading = () => {\n return !isFetched() && error() === undefined;\n };\n\n return {\n data,\n error,\n isLoading,\n };\n}\n","import { createSignal, onCleanup } from 'solid-js';\nimport type { SchemaStructure, BucketNames } from '@spooky-sync/query-builder';\nimport { fileToUint8Array } from '@spooky-sync/core';\nimport type { SyncedDb } from '../index';\nimport { useDb } from './context';\n\nexport interface FileUploadResult {\n isUploading: () => boolean;\n error: () => Error | null;\n clearError: () => void;\n upload: (path: string, file: File | Blob) => Promise<void>;\n download: (path: string) => Promise<string | null>;\n remove: (path: string) => Promise<void>;\n exists: (path: string) => Promise<boolean>;\n}\n\nexport function useFileUpload<S extends SchemaStructure>(\n bucketName: BucketNames<S>,\n): FileUploadResult;\nexport function useFileUpload<S extends SchemaStructure>(\n db: SyncedDb<S>,\n bucketName: BucketNames<S>,\n): FileUploadResult;\nexport function useFileUpload<S extends SchemaStructure>(\n dbOrBucketName: SyncedDb<S> | BucketNames<S>,\n maybeBucketName?: BucketNames<S>,\n): FileUploadResult {\n let db: SyncedDb<S>;\n let bucketName: BucketNames<S>;\n\n if (typeof dbOrBucketName === 'string') {\n db = useDb<S>();\n bucketName = dbOrBucketName as BucketNames<S>;\n } else {\n db = dbOrBucketName as SyncedDb<S>;\n // oxlint-disable-next-line no-non-null-assertion\n bucketName = maybeBucketName!;\n }\n\n const [isUploading, setIsUploading] = createSignal(false);\n const [error, setError] = createSignal<Error | null>(null);\n\n const objectUrls: string[] = [];\n onCleanup(() => {\n for (const url of objectUrls) {\n URL.revokeObjectURL(url);\n }\n });\n\n const clearError = () => setError(null);\n\n const validate = (file: File | Blob): void => {\n const config = db.getBucketConfig(bucketName as string);\n if (!config) return;\n\n if (config.maxSize !== null && config.maxSize !== undefined && file.size > config.maxSize) {\n const maxMB = (config.maxSize / (1024 * 1024)).toFixed(1);\n throw new Error(`File exceeds maximum size of ${maxMB} MB.`);\n }\n\n if (config.allowedExtensions && config.allowedExtensions.length > 0) {\n const fileName = (file as File).name;\n if (fileName) {\n const ext = fileName.split('.').pop()?.toLowerCase();\n if (!ext || !config.allowedExtensions.includes(ext)) {\n throw new Error(\n `File type not allowed. Accepted: ${config.allowedExtensions.join(', ')}.`\n );\n }\n }\n }\n };\n\n const upload = async (path: string, file: File | Blob): Promise<void> => {\n setError(null);\n try {\n validate(file);\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n return;\n }\n\n setIsUploading(true);\n try {\n const bytes = await fileToUint8Array(file);\n await db.bucket(bucketName).put(path, bytes);\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n } finally {\n setIsUploading(false);\n }\n };\n\n const download = async (path: string): Promise<string | null> => {\n setError(null);\n try {\n const content = await db.bucket(bucketName).get(path);\n if (!content) return null;\n const objectUrl = URL.createObjectURL(new Blob([content as BlobPart]));\n objectUrls.push(objectUrl);\n return objectUrl;\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n return null;\n }\n };\n\n const remove = async (path: string): Promise<void> => {\n setError(null);\n try {\n await db.bucket(bucketName).delete(path);\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n }\n };\n\n const exists = async (path: string): Promise<boolean> => {\n setError(null);\n try {\n return await db.bucket(bucketName).exists(path);\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n return false;\n }\n };\n\n return {\n isUploading,\n error,\n clearError,\n upload,\n download,\n remove,\n exists,\n };\n}\n","import { createSignal, createEffect, onCleanup, type Accessor } from 'solid-js';\nimport type { SchemaStructure, BucketNames } from '@spooky-sync/query-builder';\nimport type { SyncedDb } from '../index';\nimport { useDb } from './context';\n\nexport interface UseDownloadFileOptions {\n cache?: boolean;\n}\n\nexport interface UseDownloadFileResult {\n url: Accessor<string | null>;\n isLoading: Accessor<boolean>;\n error: Accessor<Error | null>;\n refetch: () => void;\n}\n\ninterface CacheEntry {\n url: string;\n refCount: number;\n}\n\nconst downloadCache = new Map<string, CacheEntry>();\nconst inflightRequests = new Map<string, Promise<string | null>>();\n\nfunction cacheKey(bucket: string, path: string): string {\n return `${bucket}:${path}`;\n}\n\nfunction releaseEntry(key: string): void {\n const entry = downloadCache.get(key);\n if (!entry) return;\n entry.refCount--;\n if (entry.refCount <= 0) {\n URL.revokeObjectURL(entry.url);\n downloadCache.delete(key);\n }\n}\n\nexport function useDownloadFile<S extends SchemaStructure>(\n bucketName: BucketNames<S>,\n path: Accessor<string | null | undefined>,\n options?: UseDownloadFileOptions,\n): UseDownloadFileResult;\nexport function useDownloadFile<S extends SchemaStructure>(\n db: SyncedDb<S>,\n bucketName: BucketNames<S>,\n path: Accessor<string | null | undefined>,\n options?: UseDownloadFileOptions,\n): UseDownloadFileResult;\nexport function useDownloadFile<S extends SchemaStructure>(\n dbOrBucketName: SyncedDb<S> | BucketNames<S>,\n bucketNameOrPath?: BucketNames<S> | Accessor<string | null | undefined>,\n pathOrOptions?: Accessor<string | null | undefined> | UseDownloadFileOptions,\n maybeOptions?: UseDownloadFileOptions,\n): UseDownloadFileResult {\n let db: SyncedDb<S>;\n let bucketName: BucketNames<S>;\n let path: Accessor<string | null | undefined>;\n let options: UseDownloadFileOptions;\n\n if (typeof dbOrBucketName === 'string') {\n db = useDb<S>();\n bucketName = dbOrBucketName as BucketNames<S>;\n path = bucketNameOrPath as Accessor<string | null | undefined>;\n options = (pathOrOptions as UseDownloadFileOptions) ?? {};\n } else {\n db = dbOrBucketName as SyncedDb<S>;\n bucketName = bucketNameOrPath as BucketNames<S>;\n path = pathOrOptions as Accessor<string | null | undefined>;\n options = maybeOptions ?? {};\n }\n\n const useCache = options.cache !== false;\n\n const [url, setUrl] = createSignal<string | null>(null);\n const [isLoading, setIsLoading] = createSignal(false);\n const [error, setError] = createSignal<Error | null>(null);\n\n let currentKey: string | null = null;\n let privateUrl: string | null = null;\n const [refetchSignal, setRefetchSignal] = createSignal(0);\n const refetchTrigger = () => setRefetchSignal((n) => n + 1);\n\n async function doDownload(key: string, filePath: string): Promise<string | null> {\n if (useCache) {\n // Check cache\n const cached = downloadCache.get(key);\n if (cached) {\n cached.refCount++;\n currentKey = key;\n return cached.url;\n }\n\n // Check inflight\n const inflight = inflightRequests.get(key);\n if (inflight) {\n const result = await inflight;\n if (result) {\n const entry = downloadCache.get(key);\n if (entry) {\n entry.refCount++;\n currentKey = key;\n }\n }\n return result;\n }\n\n // Start new download\n const promise = (async () => {\n const content = await db.bucket(bucketName).get(filePath);\n if (!content) return null;\n const objectUrl = URL.createObjectURL(new Blob([content as BlobPart]));\n downloadCache.set(key, { url: objectUrl, refCount: 1 });\n return objectUrl;\n })();\n\n inflightRequests.set(key, promise);\n try {\n const result = await promise;\n currentKey = key;\n return result;\n } finally {\n inflightRequests.delete(key);\n }\n } else {\n // No caching — private URL per instance\n const content = await db.bucket(bucketName).get(filePath);\n if (!content) return null;\n const objectUrl = URL.createObjectURL(new Blob([content as BlobPart]));\n privateUrl = objectUrl;\n return objectUrl;\n }\n }\n\n function releaseCurrentEntry() {\n if (useCache && currentKey) {\n releaseEntry(currentKey);\n currentKey = null;\n }\n if (!useCache && privateUrl) {\n URL.revokeObjectURL(privateUrl);\n privateUrl = null;\n }\n }\n\n createEffect(() => {\n const filePath = path();\n // Subscribe to refetch signal so effect re-runs\n refetchSignal();\n\n // Release previous entry\n releaseCurrentEntry();\n\n if (!filePath) {\n setUrl(null);\n setIsLoading(false);\n setError(null);\n return;\n }\n\n const key = cacheKey(bucketName as string, filePath);\n\n // Synchronous cache hit\n if (useCache) {\n const cached = downloadCache.get(key);\n if (cached) {\n cached.refCount++;\n currentKey = key;\n setUrl(cached.url);\n setIsLoading(false);\n setError(null);\n return;\n }\n }\n\n let cancelled = false;\n setIsLoading(true);\n setError(null);\n\n doDownload(key, filePath).then(\n (result) => {\n if (!cancelled) {\n setUrl(result);\n setIsLoading(false);\n }\n return undefined;\n },\n (err) => {\n if (!cancelled) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setIsLoading(false);\n }\n },\n );\n\n onCleanup(() => {\n cancelled = true;\n });\n });\n\n onCleanup(() => {\n releaseCurrentEntry();\n });\n\n const refetch = () => {\n // Evict current entry from cache before re-triggering\n if (useCache && currentKey) {\n const entry = downloadCache.get(currentKey);\n if (entry) {\n URL.revokeObjectURL(entry.url);\n downloadCache.delete(currentKey);\n }\n currentKey = null;\n }\n refetchTrigger();\n };\n\n return { url, isLoading, error, refetch };\n}\n","import type { JSX} from 'solid-js';\nimport { createSignal, onMount, createComponent, createMemo, mergeProps } from 'solid-js';\nimport type { SchemaStructure } from '@spooky/query-builder';\nimport type { SyncedDbConfig } from '../types';\nimport { SyncedDb } from '../index';\nimport { Sp00kyContext } from './context';\n\nexport interface Sp00kyProviderProps<S extends SchemaStructure> {\n config: SyncedDbConfig<S>;\n fallback?: JSX.Element;\n onError?: (error: Error) => void;\n onReady?: (db: SyncedDb<S>) => void;\n children: JSX.Element;\n}\n\nexport function Sp00kyProvider<S extends SchemaStructure>(\n props: Sp00kyProviderProps<S>\n): JSX.Element {\n const merged = mergeProps(\n {\n fallback: undefined as JSX.Element | undefined,\n },\n props\n );\n\n const [db, setDb] = createSignal<SyncedDb<S> | undefined>(undefined);\n\n onMount(async () => {\n try {\n const instance = new SyncedDb<S>(merged.config);\n await instance.init();\n setDb(() => instance);\n merged.onReady?.(instance);\n } catch (e) {\n const error = e instanceof Error ? e : new Error(String(e));\n if (merged.onError) {\n merged.onError(error);\n } else {\n // oxlint-disable-next-line no-console\n console.error('Sp00kyProvider: Failed to initialize database', error);\n }\n }\n });\n\n const content = createMemo(() => {\n const instance = db();\n if (!instance) return merged.fallback;\n return createComponent(Sp00kyContext.Provider, {\n value: instance,\n get children() {\n return merged.children;\n },\n });\n });\n\n return content as unknown as JSX.Element;\n}\n","import type { SyncedDbConfig } from './types';\nimport {\n Sp00kyClient,\n type Sp00kyQueryResultPromise,\n type AuthService,\n type BucketHandle,\n type UpdateOptions,\n type RunOptions,\n} from '@spooky-sync/core';\n\nimport type {\n GetTable,\n QueryBuilder,\n SchemaStructure,\n TableModel,\n TableNames,\n QueryResult,\n RelatedFieldsMap,\n RelationshipFieldsFromSchema,\n GetRelationship,\n RelatedFieldMapEntry,\n InnerQuery,\n BackendNames,\n BackendRoutes,\n RoutePayload,\n BucketNames,\n BucketDefinitionSchema,\n QueryModifier,\n QueryModifierBuilder,\n QueryInfo,\n RelationshipsMetadata,\n RelationshipDefinition,\n InferRelatedModelFromMetadata,\n GetCardinality,\n} from '@spooky-sync/query-builder';\n\nimport { RecordId, Uuid, type Surreal } from 'surrealdb';\nexport { RecordId, Uuid };\nexport type { Model, GenericModel, GenericSchema, ModelPayload } from './lib/models';\nexport { useQuery } from './lib/use-query';\nexport { useFileUpload, type FileUploadResult } from './lib/use-file-upload';\nexport { useDownloadFile, type UseDownloadFileOptions, type UseDownloadFileResult } from './lib/use-download-file';\nexport { Sp00kyProvider, type Sp00kyProviderProps } from './lib/Sp00kyProvider';\nexport { useDb } from './lib/context';\n\n// export { AuthEventTypes } from \"@spooky-sync/core\"; // TODO: Verify if AuthEventTypes exists in core\n\n\n// Re-export query builder types for convenience\nexport type {\n QueryModifier,\n QueryModifierBuilder,\n QueryInfo,\n RelationshipsMetadata,\n RelationshipDefinition,\n InferRelatedModelFromMetadata,\n GetCardinality,\n GetTable,\n TableModel,\n TableNames,\n QueryResult,\n};\n\nexport type RelationshipField<\n Schema extends SchemaStructure,\n TableName extends TableNames<Schema>,\n Field extends RelationshipFieldsFromSchema<Schema, TableName>,\n> = GetRelationship<Schema, TableName, Field>;\n\nexport type RelatedFieldsTableScoped<\n Schema extends SchemaStructure,\n TableName extends TableNames<Schema>,\n RelatedFields extends RelationshipFieldsFromSchema<Schema, TableName> =\n RelationshipFieldsFromSchema<Schema, TableName>,\n> = {\n [K in RelatedFields]: {\n to: RelationshipField<Schema, TableName, K>['to'];\n relatedFields: RelatedFieldsMap;\n cardinality: RelationshipField<Schema, TableName, K>['cardinality'];\n };\n};\n\nexport type InferModel<\n Schema extends SchemaStructure,\n TableName extends TableNames<Schema>,\n RelatedFields extends RelatedFieldsTableScoped<Schema, TableName>,\n> = QueryResult<Schema, TableName, RelatedFields, true>;\n\nexport type WithRelated<Field extends string, RelatedFields extends RelatedFieldsMap = {}> = {\n [K in Field]: Omit<RelatedFieldMapEntry, 'relatedFields'> & {\n relatedFields: RelatedFields;\n };\n};\n\nexport type WithRelatedMany<Field extends string, RelatedFields extends RelatedFieldsMap = {}> = {\n [K in Field]: {\n to: Field;\n relatedFields: RelatedFields;\n cardinality: 'many';\n };\n};\n\n/**\n * SyncedDb - A thin wrapper around sp00ky-ts for Solid.js integration\n * Delegates all logic to the underlying sp00ky-ts instance\n */\nexport class SyncedDb<S extends SchemaStructure> {\n private config: SyncedDbConfig<S>;\n private sp00ky: Sp00kyClient<S> | null = null;\n private _initialized = false;\n\n constructor(config: SyncedDbConfig<S>) {\n this.config = config;\n }\n\n public getSp00ky(): Sp00kyClient<S> {\n if (!this.sp00ky) throw new Error('SyncedDb not initialized');\n return this.sp00ky;\n }\n\n /**\n * Initialize the sp00ky-ts instance\n */\n async init(): Promise<void> {\n if (this._initialized) return;\n this.sp00ky = new Sp00kyClient<S>(this.config);\n await this.sp00ky.init();\n this._initialized = true;\n }\n\n /**\n * Create a new record in the database\n */\n async create(id: string, payload: Record<string, unknown>): Promise<void> {\n if (!this.sp00ky) throw new Error('SyncedDb not initialized');\n await this.sp00ky.create(id, payload as Record<string, unknown>);\n }\n\n /**\n * Update an existing record in the database\n */\n async update<TName extends TableNames<S>>(\n tableName: TName,\n recordId: string,\n payload: Partial<TableModel<GetTable<S, TName>>>,\n options?: UpdateOptions\n ): Promise<void> {\n if (!this.sp00ky) throw new Error('SyncedDb not initialized');\n await this.sp00ky.update(\n tableName as string,\n recordId,\n payload as Record<string, unknown>,\n options\n );\n }\n\n /**\n * Delete an existing record in the database\n */\n async delete<TName extends TableNames<S>>(\n tableName: TName,\n selector: string | InnerQuery<GetTable<S, TName>, boolean>\n ): Promise<void> {\n if (!this.sp00ky) throw new Error('SyncedDb not initialized');\n if (typeof selector !== 'string')\n throw new Error('Only string ID selectors are supported currently with core');\n await this.sp00ky.delete(tableName as string, selector);\n }\n\n /**\n * Query data from the database\n */\n public query<TName extends TableNames<S>>(\n table: TName\n ): QueryBuilder<S, TName, Sp00kyQueryResultPromise, {}, false> {\n if (!this.sp00ky) throw new Error('SyncedDb not initialized');\n return this.sp00ky.query(table, {});\n }\n\n /**\n * Run a backend operation\n */\n public async run<\n B extends BackendNames<S>,\n R extends BackendRoutes<S, B>,\n >(\n backend: B,\n path: R,\n payload: RoutePayload<S, B, R>,\n options?: RunOptions,\n ): Promise<void> {\n if (!this.sp00ky) throw new Error('SyncedDb not initialized');\n await this.sp00ky.run(backend, path, payload, options);\n }\n\n /**\n * Authenticate with the database\n */\n public async authenticate(token: string): Promise<RecordId<string>> {\n await this.sp00ky?.authenticate(token);\n // Sp00kyClient.authenticate returns whatever remote.authenticate returns (boolean or token usually?)\n // Wait, checked Sp00kyClient: return this.remote.getClient().authenticate(token);\n // SurrealDB authenticate returns void? or token?\n // Assuming void or token.\n return new RecordId('user', 'me'); // Placeholder or actual?\n }\n\n /**\n * Deauthenticate from the database\n * @deprecated Use signOut() instead\n */\n public async deauthenticate(): Promise<void> {\n await this.signOut();\n }\n\n /**\n * Sign out, clear session and local storage\n */\n public async signOut(): Promise<void> {\n if (!this.sp00ky) throw new Error('SyncedDb not initialized');\n await this.sp00ky.auth.signOut();\n }\n\n /**\n * Execute a function with direct access to the remote database connection\n */\n public async useRemote<T>(fn: (db: Surreal) => T | Promise<T>): Promise<T> {\n if (!this.sp00ky) throw new Error('SyncedDb not initialized');\n return await this.sp00ky.useRemote(fn);\n }\n /**\n * Access the remote database service directly\n */\n get remote(): Sp00kyClient<S>['remoteClient'] {\n if (!this.sp00ky) throw new Error('SyncedDb not initialized');\n return this.sp00ky.remoteClient;\n }\n\n /**\n * Access the local database service directly\n */\n get local(): Sp00kyClient<S>['localClient'] {\n if (!this.sp00ky) throw new Error('SyncedDb not initialized');\n return this.sp00ky.localClient;\n }\n\n /**\n * Access the auth service\n */\n get auth(): AuthService<S> {\n if (!this.sp00ky) throw new Error('SyncedDb not initialized');\n return this.sp00ky.auth;\n }\n\n get pendingMutationCount(): number {\n if (!this.sp00ky) throw new Error('SyncedDb not initialized');\n return this.sp00ky.pendingMutationCount;\n }\n\n subscribeToPendingMutations(cb: (count: number) => void): () => void {\n if (!this.sp00ky) throw new Error('SyncedDb not initialized');\n return this.sp00ky.subscribeToPendingMutations(cb);\n }\n\n bucket<B extends BucketNames<S>>(name: B): BucketHandle {\n if (!this.sp00ky) throw new Error('SyncedDb not initialized');\n return this.sp00ky.bucket(name);\n }\n\n getBucketConfig(name: string): BucketDefinitionSchema | undefined {\n return this.config.schema.buckets?.find((b) => b.name === name);\n }\n}\n\nexport * from './types';\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spooky-sync/client-solid",
|
|
3
|
-
"version": "0.0.1-canary.
|
|
3
|
+
"version": "0.0.1-canary.50",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "SurrealDB client with local and remote database support for browser applications",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -27,13 +27,14 @@
|
|
|
27
27
|
"database",
|
|
28
28
|
"browser",
|
|
29
29
|
"offline",
|
|
30
|
-
"sync"
|
|
30
|
+
"sync",
|
|
31
|
+
"tanstack-intent"
|
|
31
32
|
],
|
|
32
33
|
"author": "",
|
|
33
34
|
"license": "MIT",
|
|
34
35
|
"repository": {
|
|
35
36
|
"type": "git",
|
|
36
|
-
"url": "https://github.com/mono424/
|
|
37
|
+
"url": "https://github.com/mono424/sp00ky.git",
|
|
37
38
|
"directory": "packages/client-solid"
|
|
38
39
|
},
|
|
39
40
|
"publishConfig": {
|