@spooky-sync/client-solid 0.0.1-canary.26 → 0.0.1-canary.29
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 +48 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -16
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +16 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -49
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/skills/{spooky-solid → sp00ky-solid}/SKILL.md +13 -13
- package/skills/{spooky-solid → sp00ky-solid}/references/file-hooks.md +1 -1
- package/src/index.ts +44 -44
- package/src/lib/{SpookyProvider.ts → Sp00kyProvider.ts} +6 -6
- package/src/lib/context.ts +3 -3
- package/src/lib/use-query.ts +10 -10
- package/src/types/index.ts +2 -2
package/src/index.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { SyncedDbConfig } from './types';
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
Sp00kyClient,
|
|
4
4
|
AuthService,
|
|
5
5
|
BucketHandle,
|
|
6
|
-
type
|
|
6
|
+
type Sp00kyQueryResultPromise,
|
|
7
7
|
UpdateOptions,
|
|
8
8
|
RunOptions,
|
|
9
9
|
} from '@spooky-sync/core';
|
|
@@ -33,7 +33,7 @@ export type { Model, GenericModel, GenericSchema, ModelPayload } from './lib/mod
|
|
|
33
33
|
export { useQuery } from './lib/use-query';
|
|
34
34
|
export { useFileUpload, type FileUploadResult } from './lib/use-file-upload';
|
|
35
35
|
export { useDownloadFile, type UseDownloadFileOptions, type UseDownloadFileResult } from './lib/use-download-file';
|
|
36
|
-
export {
|
|
36
|
+
export { Sp00kyProvider, type Sp00kyProviderProps } from './lib/Sp00kyProvider';
|
|
37
37
|
export { useDb } from './lib/context';
|
|
38
38
|
|
|
39
39
|
// export { AuthEventTypes } from "@spooky-sync/core"; // TODO: Verify if AuthEventTypes exists in core
|
|
@@ -94,30 +94,30 @@ export type WithRelatedMany<Field extends string, RelatedFields extends RelatedF
|
|
|
94
94
|
};
|
|
95
95
|
|
|
96
96
|
/**
|
|
97
|
-
* SyncedDb - A thin wrapper around
|
|
98
|
-
* Delegates all logic to the underlying
|
|
97
|
+
* SyncedDb - A thin wrapper around sp00ky-ts for Solid.js integration
|
|
98
|
+
* Delegates all logic to the underlying sp00ky-ts instance
|
|
99
99
|
*/
|
|
100
100
|
export class SyncedDb<S extends SchemaStructure> {
|
|
101
101
|
private config: SyncedDbConfig<S>;
|
|
102
|
-
private
|
|
102
|
+
private sp00ky: Sp00kyClient<S> | null = null;
|
|
103
103
|
private _initialized = false;
|
|
104
104
|
|
|
105
105
|
constructor(config: SyncedDbConfig<S>) {
|
|
106
106
|
this.config = config;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
public
|
|
110
|
-
if (!this.
|
|
111
|
-
return this.
|
|
109
|
+
public getSp00ky(): Sp00kyClient<S> {
|
|
110
|
+
if (!this.sp00ky) throw new Error('SyncedDb not initialized');
|
|
111
|
+
return this.sp00ky;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
/**
|
|
115
|
-
* Initialize the
|
|
115
|
+
* Initialize the sp00ky-ts instance
|
|
116
116
|
*/
|
|
117
117
|
async init(): Promise<void> {
|
|
118
118
|
if (this._initialized) return;
|
|
119
|
-
this.
|
|
120
|
-
await this.
|
|
119
|
+
this.sp00ky = new Sp00kyClient<S>(this.config);
|
|
120
|
+
await this.sp00ky.init();
|
|
121
121
|
this._initialized = true;
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -125,8 +125,8 @@ export class SyncedDb<S extends SchemaStructure> {
|
|
|
125
125
|
* Create a new record in the database
|
|
126
126
|
*/
|
|
127
127
|
async create(id: string, payload: Record<string, unknown>): Promise<void> {
|
|
128
|
-
if (!this.
|
|
129
|
-
await this.
|
|
128
|
+
if (!this.sp00ky) throw new Error('SyncedDb not initialized');
|
|
129
|
+
await this.sp00ky.create(id, payload as Record<string, unknown>);
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
/**
|
|
@@ -138,8 +138,8 @@ export class SyncedDb<S extends SchemaStructure> {
|
|
|
138
138
|
payload: Partial<TableModel<GetTable<S, TName>>>,
|
|
139
139
|
options?: UpdateOptions
|
|
140
140
|
): Promise<void> {
|
|
141
|
-
if (!this.
|
|
142
|
-
await this.
|
|
141
|
+
if (!this.sp00ky) throw new Error('SyncedDb not initialized');
|
|
142
|
+
await this.sp00ky.update(
|
|
143
143
|
tableName as string,
|
|
144
144
|
recordId,
|
|
145
145
|
payload as Record<string, unknown>,
|
|
@@ -154,10 +154,10 @@ export class SyncedDb<S extends SchemaStructure> {
|
|
|
154
154
|
tableName: TName,
|
|
155
155
|
selector: string | InnerQuery<GetTable<S, TName>, boolean>
|
|
156
156
|
): Promise<void> {
|
|
157
|
-
if (!this.
|
|
157
|
+
if (!this.sp00ky) throw new Error('SyncedDb not initialized');
|
|
158
158
|
if (typeof selector !== 'string')
|
|
159
159
|
throw new Error('Only string ID selectors are supported currently with core');
|
|
160
|
-
await this.
|
|
160
|
+
await this.sp00ky.delete(tableName as string, selector);
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
/**
|
|
@@ -165,9 +165,9 @@ export class SyncedDb<S extends SchemaStructure> {
|
|
|
165
165
|
*/
|
|
166
166
|
public query<TName extends TableNames<S>>(
|
|
167
167
|
table: TName
|
|
168
|
-
): QueryBuilder<S, TName,
|
|
169
|
-
if (!this.
|
|
170
|
-
return this.
|
|
168
|
+
): QueryBuilder<S, TName, Sp00kyQueryResultPromise, {}, false> {
|
|
169
|
+
if (!this.sp00ky) throw new Error('SyncedDb not initialized');
|
|
170
|
+
return this.sp00ky.query(table, {});
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
/**
|
|
@@ -182,17 +182,17 @@ export class SyncedDb<S extends SchemaStructure> {
|
|
|
182
182
|
payload: RoutePayload<S, B, R>,
|
|
183
183
|
options?: RunOptions,
|
|
184
184
|
): Promise<void> {
|
|
185
|
-
if (!this.
|
|
186
|
-
await this.
|
|
185
|
+
if (!this.sp00ky) throw new Error('SyncedDb not initialized');
|
|
186
|
+
await this.sp00ky.run(backend, path, payload, options);
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
/**
|
|
190
190
|
* Authenticate with the database
|
|
191
191
|
*/
|
|
192
192
|
public async authenticate(token: string): Promise<RecordId<string>> {
|
|
193
|
-
const result = await this.
|
|
194
|
-
//
|
|
195
|
-
// Wait, checked
|
|
193
|
+
const result = await this.sp00ky?.authenticate(token);
|
|
194
|
+
// Sp00kyClient.authenticate returns whatever remote.authenticate returns (boolean or token usually?)
|
|
195
|
+
// Wait, checked Sp00kyClient: return this.remote.getClient().authenticate(token);
|
|
196
196
|
// SurrealDB authenticate returns void? or token?
|
|
197
197
|
// Assuming void or token.
|
|
198
198
|
return new RecordId('user', 'me'); // Placeholder or actual?
|
|
@@ -210,54 +210,54 @@ export class SyncedDb<S extends SchemaStructure> {
|
|
|
210
210
|
* Sign out, clear session and local storage
|
|
211
211
|
*/
|
|
212
212
|
public async signOut(): Promise<void> {
|
|
213
|
-
if (!this.
|
|
214
|
-
await this.
|
|
213
|
+
if (!this.sp00ky) throw new Error('SyncedDb not initialized');
|
|
214
|
+
await this.sp00ky.auth.signOut();
|
|
215
215
|
}
|
|
216
216
|
|
|
217
217
|
/**
|
|
218
218
|
* Execute a function with direct access to the remote database connection
|
|
219
219
|
*/
|
|
220
220
|
public async useRemote<T>(fn: (db: Surreal) => T | Promise<T>): Promise<T> {
|
|
221
|
-
if (!this.
|
|
222
|
-
return await this.
|
|
221
|
+
if (!this.sp00ky) throw new Error('SyncedDb not initialized');
|
|
222
|
+
return await this.sp00ky.useRemote(fn);
|
|
223
223
|
}
|
|
224
224
|
/**
|
|
225
225
|
* Access the remote database service directly
|
|
226
226
|
*/
|
|
227
|
-
get remote():
|
|
228
|
-
if (!this.
|
|
229
|
-
return this.
|
|
227
|
+
get remote(): Sp00kyClient<S>['remoteClient'] {
|
|
228
|
+
if (!this.sp00ky) throw new Error('SyncedDb not initialized');
|
|
229
|
+
return this.sp00ky.remoteClient;
|
|
230
230
|
}
|
|
231
231
|
|
|
232
232
|
/**
|
|
233
233
|
* Access the local database service directly
|
|
234
234
|
*/
|
|
235
|
-
get local():
|
|
236
|
-
if (!this.
|
|
237
|
-
return this.
|
|
235
|
+
get local(): Sp00kyClient<S>['localClient'] {
|
|
236
|
+
if (!this.sp00ky) throw new Error('SyncedDb not initialized');
|
|
237
|
+
return this.sp00ky.localClient;
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
/**
|
|
241
241
|
* Access the auth service
|
|
242
242
|
*/
|
|
243
243
|
get auth(): AuthService<S> {
|
|
244
|
-
if (!this.
|
|
245
|
-
return this.
|
|
244
|
+
if (!this.sp00ky) throw new Error('SyncedDb not initialized');
|
|
245
|
+
return this.sp00ky.auth;
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
get pendingMutationCount(): number {
|
|
249
|
-
if (!this.
|
|
250
|
-
return this.
|
|
249
|
+
if (!this.sp00ky) throw new Error('SyncedDb not initialized');
|
|
250
|
+
return this.sp00ky.pendingMutationCount;
|
|
251
251
|
}
|
|
252
252
|
|
|
253
253
|
subscribeToPendingMutations(cb: (count: number) => void): () => void {
|
|
254
|
-
if (!this.
|
|
255
|
-
return this.
|
|
254
|
+
if (!this.sp00ky) throw new Error('SyncedDb not initialized');
|
|
255
|
+
return this.sp00ky.subscribeToPendingMutations(cb);
|
|
256
256
|
}
|
|
257
257
|
|
|
258
258
|
bucket<B extends BucketNames<S>>(name: B): BucketHandle {
|
|
259
|
-
if (!this.
|
|
260
|
-
return this.
|
|
259
|
+
if (!this.sp00ky) throw new Error('SyncedDb not initialized');
|
|
260
|
+
return this.sp00ky.bucket(name);
|
|
261
261
|
}
|
|
262
262
|
|
|
263
263
|
getBucketConfig(name: string): BucketDefinitionSchema | undefined {
|
|
@@ -2,9 +2,9 @@ import { createSignal, onMount, createComponent, createMemo, JSX, mergeProps } f
|
|
|
2
2
|
import type { SchemaStructure } from '@spooky/query-builder';
|
|
3
3
|
import type { SyncedDbConfig } from '../types';
|
|
4
4
|
import { SyncedDb } from '../index';
|
|
5
|
-
import {
|
|
5
|
+
import { Sp00kyContext } from './context';
|
|
6
6
|
|
|
7
|
-
export interface
|
|
7
|
+
export interface Sp00kyProviderProps<S extends SchemaStructure> {
|
|
8
8
|
config: SyncedDbConfig<S>;
|
|
9
9
|
fallback?: JSX.Element;
|
|
10
10
|
onError?: (error: Error) => void;
|
|
@@ -12,8 +12,8 @@ export interface SpookyProviderProps<S extends SchemaStructure> {
|
|
|
12
12
|
children: JSX.Element;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export function
|
|
16
|
-
props:
|
|
15
|
+
export function Sp00kyProvider<S extends SchemaStructure>(
|
|
16
|
+
props: Sp00kyProviderProps<S>
|
|
17
17
|
): JSX.Element {
|
|
18
18
|
const merged = mergeProps(
|
|
19
19
|
{
|
|
@@ -35,7 +35,7 @@ export function SpookyProvider<S extends SchemaStructure>(
|
|
|
35
35
|
if (merged.onError) {
|
|
36
36
|
merged.onError(error);
|
|
37
37
|
} else {
|
|
38
|
-
console.error('
|
|
38
|
+
console.error('Sp00kyProvider: Failed to initialize database', error);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
});
|
|
@@ -43,7 +43,7 @@ export function SpookyProvider<S extends SchemaStructure>(
|
|
|
43
43
|
const content = createMemo(() => {
|
|
44
44
|
const instance = db();
|
|
45
45
|
if (!instance) return merged.fallback;
|
|
46
|
-
return createComponent(
|
|
46
|
+
return createComponent(Sp00kyContext.Provider, {
|
|
47
47
|
value: instance,
|
|
48
48
|
get children() {
|
|
49
49
|
return merged.children;
|
package/src/lib/context.ts
CHANGED
|
@@ -2,12 +2,12 @@ import { createContext, useContext } from 'solid-js';
|
|
|
2
2
|
import type { SchemaStructure } from '@spooky/query-builder';
|
|
3
3
|
import type { SyncedDb } from '../index';
|
|
4
4
|
|
|
5
|
-
export const
|
|
5
|
+
export const Sp00kyContext = createContext<SyncedDb<any> | undefined>();
|
|
6
6
|
|
|
7
7
|
export function useDb<S extends SchemaStructure>(): SyncedDb<S> {
|
|
8
|
-
const db = useContext(
|
|
8
|
+
const db = useContext(Sp00kyContext);
|
|
9
9
|
if (!db) {
|
|
10
|
-
throw new Error('useDb must be used within a <
|
|
10
|
+
throw new Error('useDb must be used within a <Sp00kyProvider>. Wrap your app in <Sp00kyProvider config={...}>.');
|
|
11
11
|
}
|
|
12
12
|
return db as SyncedDb<S>;
|
|
13
13
|
}
|
package/src/lib/use-query.ts
CHANGED
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
} from '@spooky-sync/query-builder';
|
|
8
8
|
import { createEffect, createSignal, onCleanup, useContext } from 'solid-js';
|
|
9
9
|
import { SyncedDb } from '..';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { Sp00kyQueryResultPromise } from '@spooky-sync/core';
|
|
11
|
+
import { Sp00kyContext } from './context';
|
|
12
12
|
|
|
13
13
|
type QueryArg<
|
|
14
14
|
S extends SchemaStructure,
|
|
@@ -17,9 +17,9 @@ type QueryArg<
|
|
|
17
17
|
RelatedFields extends Record<string, any>,
|
|
18
18
|
IsOne extends boolean,
|
|
19
19
|
> =
|
|
20
|
-
| FinalQuery<S, TableName, T, RelatedFields, IsOne,
|
|
20
|
+
| FinalQuery<S, TableName, T, RelatedFields, IsOne, Sp00kyQueryResultPromise>
|
|
21
21
|
| (() =>
|
|
22
|
-
| FinalQuery<S, TableName, T, RelatedFields, IsOne,
|
|
22
|
+
| FinalQuery<S, TableName, T, RelatedFields, IsOne, Sp00kyQueryResultPromise>
|
|
23
23
|
| null
|
|
24
24
|
| undefined);
|
|
25
25
|
|
|
@@ -82,11 +82,11 @@ export function useQuery<
|
|
|
82
82
|
options = maybeOptions;
|
|
83
83
|
} else {
|
|
84
84
|
// Context-based overload: useQuery(query, options?)
|
|
85
|
-
const contextDb = useContext(
|
|
85
|
+
const contextDb = useContext(Sp00kyContext);
|
|
86
86
|
if (!contextDb) {
|
|
87
87
|
throw new Error(
|
|
88
|
-
'useQuery: No db argument provided and no
|
|
89
|
-
'Either pass a SyncedDb instance or wrap your app in <
|
|
88
|
+
'useQuery: No db argument provided and no Sp00kyContext found. ' +
|
|
89
|
+
'Either pass a SyncedDb instance or wrap your app in <Sp00kyProvider>.'
|
|
90
90
|
);
|
|
91
91
|
}
|
|
92
92
|
db = contextDb as SyncedDb<S>;
|
|
@@ -100,16 +100,16 @@ export function useQuery<
|
|
|
100
100
|
const [unsubscribe, setUnsubscribe] = createSignal<(() => void) | undefined>(undefined);
|
|
101
101
|
let prevQueryString: string | undefined;
|
|
102
102
|
|
|
103
|
-
const
|
|
103
|
+
const sp00ky = db.getSp00ky();
|
|
104
104
|
|
|
105
105
|
const initQuery = async (
|
|
106
|
-
query: FinalQuery<S, TableName, T, RelatedFields, IsOne,
|
|
106
|
+
query: FinalQuery<S, TableName, T, RelatedFields, IsOne, Sp00kyQueryResultPromise>
|
|
107
107
|
) => {
|
|
108
108
|
const { hash } = await query.run();
|
|
109
109
|
setError(undefined);
|
|
110
110
|
|
|
111
111
|
let isFirstCall = true;
|
|
112
|
-
const unsub = await
|
|
112
|
+
const unsub = await sp00ky.subscribe(
|
|
113
113
|
hash,
|
|
114
114
|
(e) => {
|
|
115
115
|
const data = (query.isOne ? e[0] : e) as TData;
|
package/src/types/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Surreal } from 'surrealdb';
|
|
2
2
|
import type { SyncedDb } from '../index';
|
|
3
3
|
import { GenericSchema } from '../lib/models';
|
|
4
|
-
import type {
|
|
4
|
+
import type { Sp00kyConfig } from '@spooky-sync/core';
|
|
5
5
|
import type { SchemaStructure, TableNames, GetTable, TableModel } from '@spooky-sync/query-builder';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -44,7 +44,7 @@ export type InferRelationshipsFromConst<S extends SchemaStructure, Schema extend
|
|
|
44
44
|
// Prettify helper expands types for better intellisense
|
|
45
45
|
type Prettify<T> = { [K in keyof T]: T[K] } & {};
|
|
46
46
|
|
|
47
|
-
export type SyncedDbConfig<S extends SchemaStructure> = Prettify<
|
|
47
|
+
export type SyncedDbConfig<S extends SchemaStructure> = Prettify<Sp00kyConfig<S>>;
|
|
48
48
|
|
|
49
49
|
// export interface LocalDbConfig {
|
|
50
50
|
// name: string;
|