@spooky-sync/client-solid 0.0.0-canary.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +11 -0
- package/QUICK_START.md +415 -0
- package/README.md +330 -0
- package/dist/index.cjs +229 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +164 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +164 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +223 -0
- package/dist/index.js.map +1 -0
- package/package.json +60 -0
- package/src/cache/index.ts +41 -0
- package/src/cache/surrealdb-wasm-factory.ts +64 -0
- package/src/index.ts +254 -0
- package/src/lib/SpookyProvider.ts +55 -0
- package/src/lib/context.ts +13 -0
- package/src/lib/models.ts +8 -0
- package/src/lib/use-query.ts +165 -0
- package/src/types/index.ts +84 -0
- package/tsconfig.json +27 -0
- package/tsdown.config.ts +19 -0
- package/tsup.config.ts +29 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { RecordId, RecordId as RecordId$1, Surreal, Uuid } from "surrealdb";
|
|
2
|
+
import { GenericModel, GenericSchema, SchemaStructure } from "@spooky/query-builder";
|
|
3
|
+
import { AuthService, RunOptions, SpookyClient, SpookyConfig, SpookyQueryResultPromise, UpdateOptions } from "@spooky-sync/core";
|
|
4
|
+
import { BackendNames, BackendRoutes, ColumnSchema, FinalQuery, GetCardinality, GetRelationship, GetTable, GetTable as GetTable$1, InferRelatedModelFromMetadata, InnerQuery, QueryBuilder, QueryInfo, QueryModifier, QueryModifierBuilder, QueryResult, QueryResult as QueryResult$1, RelatedFieldMapEntry, RelatedFieldsMap, RelationshipDefinition, RelationshipFieldsFromSchema, RelationshipsMetadata, RoutePayload, SchemaStructure as SchemaStructure$1, TableModel, TableModel as TableModel$1, TableNames, TableNames as TableNames$1 } from "@spooky-sync/query-builder";
|
|
5
|
+
import { JSX } from "solid-js";
|
|
6
|
+
|
|
7
|
+
//#region src/lib/models.d.ts
|
|
8
|
+
type Model<T> = T;
|
|
9
|
+
type ModelPayload<T> = T & {
|
|
10
|
+
id: RecordId$1;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=models.d.ts.map
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/types/index.d.ts
|
|
15
|
+
/**
|
|
16
|
+
* Options for database provisioning
|
|
17
|
+
*/
|
|
18
|
+
interface ProvisionOptions {
|
|
19
|
+
/** Force re-provision even if schema already exists */
|
|
20
|
+
force?: boolean;
|
|
21
|
+
}
|
|
22
|
+
sideEffect();
|
|
23
|
+
type CacheStrategy = 'memory' | 'indexeddb';
|
|
24
|
+
/**
|
|
25
|
+
* Infer Schema type (Record<TableName, Model>) from schema const
|
|
26
|
+
*/
|
|
27
|
+
type InferSchemaFromConst<S extends SchemaStructure$1> = { [K in TableNames$1<S>]: TableModel$1<GetTable$1<S, K>> };
|
|
28
|
+
/**
|
|
29
|
+
* Infer Relationships type from schema const's relationships array
|
|
30
|
+
* Converts from array format to nested object format
|
|
31
|
+
*/
|
|
32
|
+
type InferRelationshipsFromConst<S extends SchemaStructure$1, Schema extends GenericSchema> = { [TableName in TableNames$1<S>]: { [Rel in Extract<S['relationships'][number], {
|
|
33
|
+
from: TableName;
|
|
34
|
+
}> as Rel['field']]: {
|
|
35
|
+
model: Rel['to'] extends keyof Schema ? Schema[Rel['to']] : any;
|
|
36
|
+
table: Rel['to'];
|
|
37
|
+
cardinality: Rel['cardinality'];
|
|
38
|
+
} } };
|
|
39
|
+
type Prettify<T> = { [K in keyof T]: T[K] } & {};
|
|
40
|
+
type SyncedDbConfig<S extends SchemaStructure$1> = Prettify<SpookyConfig<S>>;
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/lib/use-query.d.ts
|
|
43
|
+
type QueryArg<S extends SchemaStructure$1, TableName extends TableNames$1<S>, T extends {
|
|
44
|
+
columns: Record<string, ColumnSchema>;
|
|
45
|
+
}, RelatedFields extends Record<string, any>, IsOne extends boolean> = FinalQuery<S, TableName, T, RelatedFields, IsOne, SpookyQueryResultPromise> | (() => FinalQuery<S, TableName, T, RelatedFields, IsOne, SpookyQueryResultPromise> | null | undefined);
|
|
46
|
+
type QueryOptions = {
|
|
47
|
+
enabled?: () => boolean;
|
|
48
|
+
};
|
|
49
|
+
declare function useQuery<S extends SchemaStructure$1, TableName extends TableNames$1<S>, T extends {
|
|
50
|
+
columns: Record<string, ColumnSchema>;
|
|
51
|
+
}, RelatedFields extends Record<string, any>, IsOne extends boolean, TData = QueryResult$1<S, TableName, RelatedFields, IsOne> | null>(finalQuery: QueryArg<S, TableName, T, RelatedFields, IsOne>, options?: QueryOptions): {
|
|
52
|
+
data: () => TData | undefined;
|
|
53
|
+
error: () => Error | undefined;
|
|
54
|
+
isLoading: () => boolean;
|
|
55
|
+
};
|
|
56
|
+
declare function useQuery<S extends SchemaStructure$1, TableName extends TableNames$1<S>, T extends {
|
|
57
|
+
columns: Record<string, ColumnSchema>;
|
|
58
|
+
}, RelatedFields extends Record<string, any>, IsOne extends boolean, TData = QueryResult$1<S, TableName, RelatedFields, IsOne> | null>(db: SyncedDb<S>, finalQuery: QueryArg<S, TableName, T, RelatedFields, IsOne>, options?: QueryOptions): {
|
|
59
|
+
data: () => TData | undefined;
|
|
60
|
+
error: () => Error | undefined;
|
|
61
|
+
isLoading: () => boolean;
|
|
62
|
+
};
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/lib/SpookyProvider.d.ts
|
|
65
|
+
interface SpookyProviderProps<S extends SchemaStructure> {
|
|
66
|
+
config: SyncedDbConfig<S>;
|
|
67
|
+
fallback?: JSX.Element;
|
|
68
|
+
onError?: (error: Error) => void;
|
|
69
|
+
onReady?: (db: SyncedDb<S>) => void;
|
|
70
|
+
children: JSX.Element;
|
|
71
|
+
}
|
|
72
|
+
declare function SpookyProvider<S extends SchemaStructure>(props: SpookyProviderProps<S>): JSX.Element;
|
|
73
|
+
//# sourceMappingURL=SpookyProvider.d.ts.map
|
|
74
|
+
//#endregion
|
|
75
|
+
//#region src/lib/context.d.ts
|
|
76
|
+
declare function useDb<S extends SchemaStructure>(): SyncedDb<S>;
|
|
77
|
+
//# sourceMappingURL=context.d.ts.map
|
|
78
|
+
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region src/index.d.ts
|
|
81
|
+
type RelationshipField<Schema extends SchemaStructure$1, TableName extends TableNames$1<Schema>, Field extends RelationshipFieldsFromSchema<Schema, TableName>> = GetRelationship<Schema, TableName, Field>;
|
|
82
|
+
type RelatedFieldsTableScoped<Schema extends SchemaStructure$1, TableName extends TableNames$1<Schema>, RelatedFields extends RelationshipFieldsFromSchema<Schema, TableName> = RelationshipFieldsFromSchema<Schema, TableName>> = { [K in RelatedFields]: {
|
|
83
|
+
to: RelationshipField<Schema, TableName, K>['to'];
|
|
84
|
+
relatedFields: RelatedFieldsMap;
|
|
85
|
+
cardinality: RelationshipField<Schema, TableName, K>['cardinality'];
|
|
86
|
+
} };
|
|
87
|
+
type InferModel<Schema extends SchemaStructure$1, TableName extends TableNames$1<Schema>, RelatedFields extends RelatedFieldsTableScoped<Schema, TableName>> = QueryResult$1<Schema, TableName, RelatedFields, true>;
|
|
88
|
+
type WithRelated<Field extends string, RelatedFields extends RelatedFieldsMap = {}> = { [K in Field]: Omit<RelatedFieldMapEntry, 'relatedFields'> & {
|
|
89
|
+
relatedFields: RelatedFields;
|
|
90
|
+
} };
|
|
91
|
+
type WithRelatedMany<Field extends string, RelatedFields extends RelatedFieldsMap = {}> = { [K in Field]: {
|
|
92
|
+
to: Field;
|
|
93
|
+
relatedFields: RelatedFields;
|
|
94
|
+
cardinality: 'many';
|
|
95
|
+
} };
|
|
96
|
+
/**
|
|
97
|
+
* SyncedDb - A thin wrapper around spooky-ts for Solid.js integration
|
|
98
|
+
* Delegates all logic to the underlying spooky-ts instance
|
|
99
|
+
*/
|
|
100
|
+
declare class SyncedDb<S extends SchemaStructure$1> {
|
|
101
|
+
private config;
|
|
102
|
+
private spooky;
|
|
103
|
+
private _initialized;
|
|
104
|
+
constructor(config: SyncedDbConfig<S>);
|
|
105
|
+
getSpooky(): SpookyClient<S>;
|
|
106
|
+
/**
|
|
107
|
+
* Initialize the spooky-ts instance
|
|
108
|
+
*/
|
|
109
|
+
init(): Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* Create a new record in the database
|
|
112
|
+
*/
|
|
113
|
+
create(id: string, payload: Record<string, unknown>): Promise<void>;
|
|
114
|
+
/**
|
|
115
|
+
* Update an existing record in the database
|
|
116
|
+
*/
|
|
117
|
+
update<TName extends TableNames$1<S>>(tableName: TName, recordId: string, payload: Partial<TableModel$1<GetTable$1<S, TName>>>, options?: UpdateOptions): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* Delete an existing record in the database
|
|
120
|
+
*/
|
|
121
|
+
delete<TName extends TableNames$1<S>>(tableName: TName, selector: string | InnerQuery<GetTable$1<S, TName>, boolean>): Promise<void>;
|
|
122
|
+
/**
|
|
123
|
+
* Query data from the database
|
|
124
|
+
*/
|
|
125
|
+
query<TName extends TableNames$1<S>>(table: TName): QueryBuilder<S, TName, SpookyQueryResultPromise, {}, false>;
|
|
126
|
+
/**
|
|
127
|
+
* Run a backend operation
|
|
128
|
+
*/
|
|
129
|
+
run<B extends BackendNames<S>, R extends BackendRoutes<S, B>>(backend: B, path: R, payload: RoutePayload<S, B, R>, options?: RunOptions): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Authenticate with the database
|
|
132
|
+
*/
|
|
133
|
+
authenticate(token: string): Promise<RecordId<string>>;
|
|
134
|
+
/**
|
|
135
|
+
* Deauthenticate from the database
|
|
136
|
+
* @deprecated Use signOut() instead
|
|
137
|
+
*/
|
|
138
|
+
deauthenticate(): Promise<void>;
|
|
139
|
+
/**
|
|
140
|
+
* Sign out, clear session and local storage
|
|
141
|
+
*/
|
|
142
|
+
signOut(): Promise<void>;
|
|
143
|
+
/**
|
|
144
|
+
* Execute a function with direct access to the remote database connection
|
|
145
|
+
*/
|
|
146
|
+
useRemote<T>(fn: (db: Surreal) => T | Promise<T>): Promise<T>;
|
|
147
|
+
/**
|
|
148
|
+
* Access the remote database service directly
|
|
149
|
+
*/
|
|
150
|
+
get remote(): SpookyClient<S>['remoteClient'];
|
|
151
|
+
/**
|
|
152
|
+
* Access the local database service directly
|
|
153
|
+
*/
|
|
154
|
+
get local(): SpookyClient<S>['localClient'];
|
|
155
|
+
/**
|
|
156
|
+
* Access the auth service
|
|
157
|
+
*/
|
|
158
|
+
get auth(): AuthService<S>;
|
|
159
|
+
get pendingMutationCount(): number;
|
|
160
|
+
subscribeToPendingMutations(cb: (count: number) => void): () => void;
|
|
161
|
+
}
|
|
162
|
+
//#endregion
|
|
163
|
+
export { CacheStrategy, 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, SpookyProvider, type SpookyProviderProps, SyncedDb, SyncedDbConfig, type TableModel, type TableNames, Uuid, WithRelated, WithRelatedMany, useDb, useQuery };
|
|
164
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/lib/models.ts","../../../src/types/index.ts","../../../src/lib/use-query.ts","../../../src/lib/SpookyProvider.ts","../../../src/lib/context.ts","../../../src/index.ts"],"sourcesContent":[],"mappings":"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;;;AJCrB,KK4C5B,iBL5C4B,CAAA,eK6CvB,iBL7CuB,EAAA,kBK8CpB,YL9CoB,CK8CT,ML9CS,CAAA,EAAA,cK+CxB,4BL/CwB,CK+CK,ML/CL,EK+Ca,SL/Cb,CAAA,CAAA,GKgDpC,eLhDoC,CKgDpB,MLhDoB,EKgDZ,SLhDY,EKgDD,KLhDC,CAAA;AAAQ,KKkDpC,wBLlDoC,CAAA,eKmD/B,iBLnD+B,EAAA,kBKoD5B,YLpD4B,CKoDjB,MLpDiB,CAAA,EAAA,sBKqDxB,4BLrDwB,CKqDK,MLrDL,EKqDa,SLrDb,CAAA,GKsD5C,4BLtD4C,CKsDf,MLtDe,EKsDP,SLtDO,CAAA,CAAA,GAAA,QKwDxC;MACA,kBAAkB,QAAQ,WAAW;iBAC1B;EJxDF,WAAA,EIyDA,iBJzDgB,CIyDE,MJzDF,EIyDU,SJzDV,EIyDqB,CJzDrB,CAAA,CAAA,aAAA,CAAA;AAOhB,CAAA,EAIjB;AAKY,KI6CA,UJ7CA,CAAA,eI8CK,iBJ9Ce,EAAA,kBI+CZ,YJ/CY,CI+CD,MJ/CC,CAAA,EAAA,sBIgDR,wBJhDQ,CIgDiB,MJhDjB,EIgDyB,SJhDzB,CAAA,CAAA,GIiD5B,aJjD4B,CIiDhB,MJjDgB,EIiDR,SJjDQ,EIiDG,aJjDH,EAAA,IAAA,CAAA;AAAA,KImDpB,WJnDoB,CAAA,cAAA,MAAA,EAAA,sBImDoC,gBJnDpC,GAAA,CAAA,CAAA,CAAA,GAAA,QIoDxB,KJpDmC,GIoD3B,IJpD2B,CIoDtB,oBJpDsB,EAAA,eAAA,CAAA,GAAA;EACxB,aAAA,EIoDA,aJpDA;;AAA4B,KIwDnC,eJxDmC,CAAA,cAAA,MAAA,EAAA,sBIwDyB,gBJxDzB,GAAA,CAAA,CAAA,CAAA,GAAA,QIyDvC,KJzD2B,GAAA;EAAX,EAAA,EI0DhB,KJ1DgB;EAAU,aAAA,EI2Df,aJ3De;EAOtB,WAAA,EAAA,MAAA;AAA2B,CAAA;;;;;AAEiB,cI2D3C,QJ3D2C,CAAA,UI2DxB,iBJ3DwB,CAAA,CAAA;UAA5C,MAAA;UAA4D,MAAA;UAC3D,YAAA;aAAwB,CAAA,MAAA,EI+Df,cJ/De,CI+DA,CJ/DA,CAAA;WAAS,CAAA,CAAA,EImExB,YJnEwB,CImEX,CJnEW,CAAA;;;;EAExB,IAAA,CAAA,CAAA,EIyEN,OJzEM,CAAA,IAAA,CAAA;EAMjB;;;QAAgC,CAAA,EAAA,EAAA,MAAA,EAAA,OAAA,EI6ED,MJ7EC,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,EI6EyB,OJ7EzB,CAAA,IAAA,CAAA;;;AAErC;EAA0B,MAAA,CAAA,cImFG,YJnFH,CImFc,CJnFd,CAAA,CAAA,CAAA,SAAA,EIoFX,KJpFW,EAAA,QAAA,EAAA,MAAA,EAAA,OAAA,EIsFb,OJtFa,CIsFL,YJtFK,CIsFM,UJtFN,CIsFe,CJtFf,EIsFkB,KJtFlB,CAAA,CAAA,CAAA,EAAA,OAAA,CAAA,EIuFZ,aJvFY,CAAA,EIwFrB,OJxFqB,CAAA,IAAA,CAAA;;;;QAA8B,CAAA,cIqG3B,YJrG2B,CIqGhB,CJrGgB,CAAA,CAAA,CAAA,SAAA,EIsGzC,KJtGyC,EAAA,QAAA,EAAA,MAAA,GIuGjC,UJvGiC,CIuGtB,UJvGsB,CIuGb,CJvGa,EIuGV,KJvGU,CAAA,EAAA,OAAA,CAAA,CAAA,EIwGnD,OJxGmD,CAAA,IAAA,CAAA;EAAQ;;;sBIkHnC,aAAW,WAC7B,QACN,aAAa,GAAG,OAAO;EHtJvB;;;KAE0B,CAAA,UG6JjB,YH7JiB,CG6JJ,CH7JI,CAAA,EAAA,UG8JjB,aH9JiB,CG8JH,CH9JG,EG8JA,CH9JA,CAAA,CAAA,CAAA,OAAA,EGgKlB,CHhKkB,EAAA,IAAA,EGiKrB,CHjKqB,EAAA,OAAA,EGkKlB,YHlKkB,CGkKL,CHlKK,EGkKF,CHlKE,EGkKC,CHlKD,CAAA,EAAA,OAAA,CAAA,EGmKjB,UHnKiB,CAAA,EGoK1B,OHpK0B,CAAA,IAAA,CAAA;;;;cAEP,CAAA,KAAA,EAAA,MAAA,CAAA,EG0KoB,OH1KpB,CG0K4B,QH1K5B,CAAA,MAAA,CAAA,CAAA;;;;;gBAGuB,CAAA,CAAA,EGoLd,OHpLc,CAAA,IAAA,CAAA;;;;SAEzB,CAAA,CAAA,EGyLI,OHzLJ,CAAA,IAAA,CAAA;;;;WAAoC,CAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA,EAAA,EGiMrB,OHjMqB,EAAA,GGiMT,CHjMS,GGiML,OHjMK,CGiMG,CHjMH,CAAA,CAAA,EGiMQ,OHjMR,CGiMgB,CHjMhB,CAAA;;;AAAxC;EAOF,IAAA,MAAA,CAAA,CAAQ,EGiMR,YHjMQ,CGiMK,CHjML,CAAA,CAAA,cAAA,CAAA;EAAA;;;MAEJ,KAAA,CAAA,CAAA,EGuML,YHvMK,CGuMQ,CHvMR,CAAA,CAAA,aAAA,CAAA;;;;MAIE,IAAA,CAAA,CAAA,EG2MR,WH3MQ,CG2MI,CH3MJ,CAAA;MAAG,oBAAA,CAAA,CAAA,EAAA,MAAA;6BAAW,CAAA,EAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,GAAA,IAAA,CAAA,EAAA,GAAA,GAAA,IAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { AuthService, RunOptions, SpookyClient, SpookyConfig, SpookyQueryResultPromise, UpdateOptions } from "@spooky-sync/core";
|
|
2
|
+
import { RecordId, RecordId as RecordId$1, Surreal, Uuid } from "surrealdb";
|
|
3
|
+
import { JSX } from "solid-js";
|
|
4
|
+
import { GenericModel, GenericSchema, SchemaStructure } from "@spooky/query-builder";
|
|
5
|
+
import { BackendNames, BackendRoutes, ColumnSchema, FinalQuery, GetCardinality, GetRelationship, GetTable, GetTable as GetTable$1, InferRelatedModelFromMetadata, InnerQuery, QueryBuilder, QueryInfo, QueryModifier, QueryModifierBuilder, QueryResult, QueryResult as QueryResult$1, RelatedFieldMapEntry, RelatedFieldsMap, RelationshipDefinition, RelationshipFieldsFromSchema, RelationshipsMetadata, RoutePayload, SchemaStructure as SchemaStructure$1, TableModel, TableModel as TableModel$1, TableNames, TableNames as TableNames$1 } from "@spooky-sync/query-builder";
|
|
6
|
+
|
|
7
|
+
//#region src/lib/models.d.ts
|
|
8
|
+
type Model<T> = T;
|
|
9
|
+
type ModelPayload<T> = T & {
|
|
10
|
+
id: RecordId$1;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=models.d.ts.map
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/types/index.d.ts
|
|
15
|
+
/**
|
|
16
|
+
* Options for database provisioning
|
|
17
|
+
*/
|
|
18
|
+
interface ProvisionOptions {
|
|
19
|
+
/** Force re-provision even if schema already exists */
|
|
20
|
+
force?: boolean;
|
|
21
|
+
}
|
|
22
|
+
sideEffect();
|
|
23
|
+
type CacheStrategy = 'memory' | 'indexeddb';
|
|
24
|
+
/**
|
|
25
|
+
* Infer Schema type (Record<TableName, Model>) from schema const
|
|
26
|
+
*/
|
|
27
|
+
type InferSchemaFromConst<S extends SchemaStructure$1> = { [K in TableNames$1<S>]: TableModel$1<GetTable$1<S, K>> };
|
|
28
|
+
/**
|
|
29
|
+
* Infer Relationships type from schema const's relationships array
|
|
30
|
+
* Converts from array format to nested object format
|
|
31
|
+
*/
|
|
32
|
+
type InferRelationshipsFromConst<S extends SchemaStructure$1, Schema extends GenericSchema> = { [TableName in TableNames$1<S>]: { [Rel in Extract<S['relationships'][number], {
|
|
33
|
+
from: TableName;
|
|
34
|
+
}> as Rel['field']]: {
|
|
35
|
+
model: Rel['to'] extends keyof Schema ? Schema[Rel['to']] : any;
|
|
36
|
+
table: Rel['to'];
|
|
37
|
+
cardinality: Rel['cardinality'];
|
|
38
|
+
} } };
|
|
39
|
+
type Prettify<T> = { [K in keyof T]: T[K] } & {};
|
|
40
|
+
type SyncedDbConfig<S extends SchemaStructure$1> = Prettify<SpookyConfig<S>>;
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/lib/use-query.d.ts
|
|
43
|
+
type QueryArg<S extends SchemaStructure$1, TableName extends TableNames$1<S>, T extends {
|
|
44
|
+
columns: Record<string, ColumnSchema>;
|
|
45
|
+
}, RelatedFields extends Record<string, any>, IsOne extends boolean> = FinalQuery<S, TableName, T, RelatedFields, IsOne, SpookyQueryResultPromise> | (() => FinalQuery<S, TableName, T, RelatedFields, IsOne, SpookyQueryResultPromise> | null | undefined);
|
|
46
|
+
type QueryOptions = {
|
|
47
|
+
enabled?: () => boolean;
|
|
48
|
+
};
|
|
49
|
+
declare function useQuery<S extends SchemaStructure$1, TableName extends TableNames$1<S>, T extends {
|
|
50
|
+
columns: Record<string, ColumnSchema>;
|
|
51
|
+
}, RelatedFields extends Record<string, any>, IsOne extends boolean, TData = QueryResult$1<S, TableName, RelatedFields, IsOne> | null>(finalQuery: QueryArg<S, TableName, T, RelatedFields, IsOne>, options?: QueryOptions): {
|
|
52
|
+
data: () => TData | undefined;
|
|
53
|
+
error: () => Error | undefined;
|
|
54
|
+
isLoading: () => boolean;
|
|
55
|
+
};
|
|
56
|
+
declare function useQuery<S extends SchemaStructure$1, TableName extends TableNames$1<S>, T extends {
|
|
57
|
+
columns: Record<string, ColumnSchema>;
|
|
58
|
+
}, RelatedFields extends Record<string, any>, IsOne extends boolean, TData = QueryResult$1<S, TableName, RelatedFields, IsOne> | null>(db: SyncedDb<S>, finalQuery: QueryArg<S, TableName, T, RelatedFields, IsOne>, options?: QueryOptions): {
|
|
59
|
+
data: () => TData | undefined;
|
|
60
|
+
error: () => Error | undefined;
|
|
61
|
+
isLoading: () => boolean;
|
|
62
|
+
};
|
|
63
|
+
//#endregion
|
|
64
|
+
//#region src/lib/SpookyProvider.d.ts
|
|
65
|
+
interface SpookyProviderProps<S extends SchemaStructure> {
|
|
66
|
+
config: SyncedDbConfig<S>;
|
|
67
|
+
fallback?: JSX.Element;
|
|
68
|
+
onError?: (error: Error) => void;
|
|
69
|
+
onReady?: (db: SyncedDb<S>) => void;
|
|
70
|
+
children: JSX.Element;
|
|
71
|
+
}
|
|
72
|
+
declare function SpookyProvider<S extends SchemaStructure>(props: SpookyProviderProps<S>): JSX.Element;
|
|
73
|
+
//# sourceMappingURL=SpookyProvider.d.ts.map
|
|
74
|
+
//#endregion
|
|
75
|
+
//#region src/lib/context.d.ts
|
|
76
|
+
declare function useDb<S extends SchemaStructure>(): SyncedDb<S>;
|
|
77
|
+
//# sourceMappingURL=context.d.ts.map
|
|
78
|
+
|
|
79
|
+
//#endregion
|
|
80
|
+
//#region src/index.d.ts
|
|
81
|
+
type RelationshipField<Schema extends SchemaStructure$1, TableName extends TableNames$1<Schema>, Field extends RelationshipFieldsFromSchema<Schema, TableName>> = GetRelationship<Schema, TableName, Field>;
|
|
82
|
+
type RelatedFieldsTableScoped<Schema extends SchemaStructure$1, TableName extends TableNames$1<Schema>, RelatedFields extends RelationshipFieldsFromSchema<Schema, TableName> = RelationshipFieldsFromSchema<Schema, TableName>> = { [K in RelatedFields]: {
|
|
83
|
+
to: RelationshipField<Schema, TableName, K>['to'];
|
|
84
|
+
relatedFields: RelatedFieldsMap;
|
|
85
|
+
cardinality: RelationshipField<Schema, TableName, K>['cardinality'];
|
|
86
|
+
} };
|
|
87
|
+
type InferModel<Schema extends SchemaStructure$1, TableName extends TableNames$1<Schema>, RelatedFields extends RelatedFieldsTableScoped<Schema, TableName>> = QueryResult$1<Schema, TableName, RelatedFields, true>;
|
|
88
|
+
type WithRelated<Field extends string, RelatedFields extends RelatedFieldsMap = {}> = { [K in Field]: Omit<RelatedFieldMapEntry, 'relatedFields'> & {
|
|
89
|
+
relatedFields: RelatedFields;
|
|
90
|
+
} };
|
|
91
|
+
type WithRelatedMany<Field extends string, RelatedFields extends RelatedFieldsMap = {}> = { [K in Field]: {
|
|
92
|
+
to: Field;
|
|
93
|
+
relatedFields: RelatedFields;
|
|
94
|
+
cardinality: 'many';
|
|
95
|
+
} };
|
|
96
|
+
/**
|
|
97
|
+
* SyncedDb - A thin wrapper around spooky-ts for Solid.js integration
|
|
98
|
+
* Delegates all logic to the underlying spooky-ts instance
|
|
99
|
+
*/
|
|
100
|
+
declare class SyncedDb<S extends SchemaStructure$1> {
|
|
101
|
+
private config;
|
|
102
|
+
private spooky;
|
|
103
|
+
private _initialized;
|
|
104
|
+
constructor(config: SyncedDbConfig<S>);
|
|
105
|
+
getSpooky(): SpookyClient<S>;
|
|
106
|
+
/**
|
|
107
|
+
* Initialize the spooky-ts instance
|
|
108
|
+
*/
|
|
109
|
+
init(): Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* Create a new record in the database
|
|
112
|
+
*/
|
|
113
|
+
create(id: string, payload: Record<string, unknown>): Promise<void>;
|
|
114
|
+
/**
|
|
115
|
+
* Update an existing record in the database
|
|
116
|
+
*/
|
|
117
|
+
update<TName extends TableNames$1<S>>(tableName: TName, recordId: string, payload: Partial<TableModel$1<GetTable$1<S, TName>>>, options?: UpdateOptions): Promise<void>;
|
|
118
|
+
/**
|
|
119
|
+
* Delete an existing record in the database
|
|
120
|
+
*/
|
|
121
|
+
delete<TName extends TableNames$1<S>>(tableName: TName, selector: string | InnerQuery<GetTable$1<S, TName>, boolean>): Promise<void>;
|
|
122
|
+
/**
|
|
123
|
+
* Query data from the database
|
|
124
|
+
*/
|
|
125
|
+
query<TName extends TableNames$1<S>>(table: TName): QueryBuilder<S, TName, SpookyQueryResultPromise, {}, false>;
|
|
126
|
+
/**
|
|
127
|
+
* Run a backend operation
|
|
128
|
+
*/
|
|
129
|
+
run<B extends BackendNames<S>, R extends BackendRoutes<S, B>>(backend: B, path: R, payload: RoutePayload<S, B, R>, options?: RunOptions): Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Authenticate with the database
|
|
132
|
+
*/
|
|
133
|
+
authenticate(token: string): Promise<RecordId<string>>;
|
|
134
|
+
/**
|
|
135
|
+
* Deauthenticate from the database
|
|
136
|
+
* @deprecated Use signOut() instead
|
|
137
|
+
*/
|
|
138
|
+
deauthenticate(): Promise<void>;
|
|
139
|
+
/**
|
|
140
|
+
* Sign out, clear session and local storage
|
|
141
|
+
*/
|
|
142
|
+
signOut(): Promise<void>;
|
|
143
|
+
/**
|
|
144
|
+
* Execute a function with direct access to the remote database connection
|
|
145
|
+
*/
|
|
146
|
+
useRemote<T>(fn: (db: Surreal) => T | Promise<T>): Promise<T>;
|
|
147
|
+
/**
|
|
148
|
+
* Access the remote database service directly
|
|
149
|
+
*/
|
|
150
|
+
get remote(): SpookyClient<S>['remoteClient'];
|
|
151
|
+
/**
|
|
152
|
+
* Access the local database service directly
|
|
153
|
+
*/
|
|
154
|
+
get local(): SpookyClient<S>['localClient'];
|
|
155
|
+
/**
|
|
156
|
+
* Access the auth service
|
|
157
|
+
*/
|
|
158
|
+
get auth(): AuthService<S>;
|
|
159
|
+
get pendingMutationCount(): number;
|
|
160
|
+
subscribeToPendingMutations(cb: (count: number) => void): () => void;
|
|
161
|
+
}
|
|
162
|
+
//#endregion
|
|
163
|
+
export { CacheStrategy, 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, SpookyProvider, type SpookyProviderProps, SyncedDb, SyncedDbConfig, type TableModel, type TableNames, Uuid, WithRelated, WithRelatedMany, useDb, useQuery };
|
|
164
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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/SpookyProvider.ts","../../../src/lib/context.ts","../../../src/index.ts"],"sourcesContent":[],"mappings":"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;;;AJCrB,KK4C5B,iBL5C4B,CAAA,eK6CvB,iBL7CuB,EAAA,kBK8CpB,YL9CoB,CK8CT,ML9CS,CAAA,EAAA,cK+CxB,4BL/CwB,CK+CK,ML/CL,EK+Ca,SL/Cb,CAAA,CAAA,GKgDpC,eLhDoC,CKgDpB,MLhDoB,EKgDZ,SLhDY,EKgDD,KLhDC,CAAA;AAAQ,KKkDpC,wBLlDoC,CAAA,eKmD/B,iBLnD+B,EAAA,kBKoD5B,YLpD4B,CKoDjB,MLpDiB,CAAA,EAAA,sBKqDxB,4BLrDwB,CKqDK,MLrDL,EKqDa,SLrDb,CAAA,GKsD5C,4BLtD4C,CKsDf,MLtDe,EKsDP,SLtDO,CAAA,CAAA,GAAA,QKwDxC;MACA,kBAAkB,QAAQ,WAAW;iBAC1B;EJxDF,WAAA,EIyDA,iBJzDgB,CIyDE,MJzDF,EIyDU,SJzDV,EIyDqB,CJzDrB,CAAA,CAAA,aAAA,CAAA;AAOhB,CAAA,EAIjB;AAKY,KI6CA,UJ7CA,CAAA,eI8CK,iBJ9Ce,EAAA,kBI+CZ,YJ/CY,CI+CD,MJ/CC,CAAA,EAAA,sBIgDR,wBJhDQ,CIgDiB,MJhDjB,EIgDyB,SJhDzB,CAAA,CAAA,GIiD5B,aJjD4B,CIiDhB,MJjDgB,EIiDR,SJjDQ,EIiDG,aJjDH,EAAA,IAAA,CAAA;AAAA,KImDpB,WJnDoB,CAAA,cAAA,MAAA,EAAA,sBImDoC,gBJnDpC,GAAA,CAAA,CAAA,CAAA,GAAA,QIoDxB,KJpDmC,GIoD3B,IJpD2B,CIoDtB,oBJpDsB,EAAA,eAAA,CAAA,GAAA;EACxB,aAAA,EIoDA,aJpDA;;AAA4B,KIwDnC,eJxDmC,CAAA,cAAA,MAAA,EAAA,sBIwDyB,gBJxDzB,GAAA,CAAA,CAAA,CAAA,GAAA,QIyDvC,KJzD2B,GAAA;EAAX,EAAA,EI0DhB,KJ1DgB;EAAU,aAAA,EI2Df,aJ3De;EAOtB,WAAA,EAAA,MAAA;AAA2B,CAAA;;;;;AAEiB,cI2D3C,QJ3D2C,CAAA,UI2DxB,iBJ3DwB,CAAA,CAAA;UAA5C,MAAA;UAA4D,MAAA;UAC3D,YAAA;aAAwB,CAAA,MAAA,EI+Df,cJ/De,CI+DA,CJ/DA,CAAA;WAAS,CAAA,CAAA,EImExB,YJnEwB,CImEX,CJnEW,CAAA;;;;EAExB,IAAA,CAAA,CAAA,EIyEN,OJzEM,CAAA,IAAA,CAAA;EAMjB;;;QAAgC,CAAA,EAAA,EAAA,MAAA,EAAA,OAAA,EI6ED,MJ7EC,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,EI6EyB,OJ7EzB,CAAA,IAAA,CAAA;;;AAErC;EAA0B,MAAA,CAAA,cImFG,YJnFH,CImFc,CJnFd,CAAA,CAAA,CAAA,SAAA,EIoFX,KJpFW,EAAA,QAAA,EAAA,MAAA,EAAA,OAAA,EIsFb,OJtFa,CIsFL,YJtFK,CIsFM,UJtFN,CIsFe,CJtFf,EIsFkB,KJtFlB,CAAA,CAAA,CAAA,EAAA,OAAA,CAAA,EIuFZ,aJvFY,CAAA,EIwFrB,OJxFqB,CAAA,IAAA,CAAA;;;;QAA8B,CAAA,cIqG3B,YJrG2B,CIqGhB,CJrGgB,CAAA,CAAA,CAAA,SAAA,EIsGzC,KJtGyC,EAAA,QAAA,EAAA,MAAA,GIuGjC,UJvGiC,CIuGtB,UJvGsB,CIuGb,CJvGa,EIuGV,KJvGU,CAAA,EAAA,OAAA,CAAA,CAAA,EIwGnD,OJxGmD,CAAA,IAAA,CAAA;EAAQ;;;sBIkHnC,aAAW,WAC7B,QACN,aAAa,GAAG,OAAO;EHtJvB;;;KAE0B,CAAA,UG6JjB,YH7JiB,CG6JJ,CH7JI,CAAA,EAAA,UG8JjB,aH9JiB,CG8JH,CH9JG,EG8JA,CH9JA,CAAA,CAAA,CAAA,OAAA,EGgKlB,CHhKkB,EAAA,IAAA,EGiKrB,CHjKqB,EAAA,OAAA,EGkKlB,YHlKkB,CGkKL,CHlKK,EGkKF,CHlKE,EGkKC,CHlKD,CAAA,EAAA,OAAA,CAAA,EGmKjB,UHnKiB,CAAA,EGoK1B,OHpK0B,CAAA,IAAA,CAAA;;;;cAEP,CAAA,KAAA,EAAA,MAAA,CAAA,EG0KoB,OH1KpB,CG0K4B,QH1K5B,CAAA,MAAA,CAAA,CAAA;;;;;gBAGuB,CAAA,CAAA,EGoLd,OHpLc,CAAA,IAAA,CAAA;;;;SAEzB,CAAA,CAAA,EGyLI,OHzLJ,CAAA,IAAA,CAAA;;;;WAAoC,CAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA,EAAA,EGiMrB,OHjMqB,EAAA,GGiMT,CHjMS,GGiML,OHjMK,CGiMG,CHjMH,CAAA,CAAA,EGiMQ,OHjMR,CGiMgB,CHjMhB,CAAA;;;AAAxC;EAOF,IAAA,MAAA,CAAA,CAAQ,EGiMR,YHjMQ,CGiMK,CHjML,CAAA,CAAA,cAAA,CAAA;EAAA;;;MAEJ,KAAA,CAAA,CAAA,EGuML,YHvMK,CGuMQ,CHvMR,CAAA,CAAA,aAAA,CAAA;;;;MAIE,IAAA,CAAA,CAAA,EG2MR,WH3MQ,CG2MI,CH3MJ,CAAA;MAAG,oBAAA,CAAA,CAAA,EAAA,MAAA;6BAAW,CAAA,EAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,GAAA,IAAA,CAAA,EAAA,GAAA,GAAA,IAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { SpookyClient } from "@spooky-sync/core";
|
|
2
|
+
import { RecordId, Uuid } from "surrealdb";
|
|
3
|
+
import { createComponent, createContext, createEffect, createMemo, createSignal, mergeProps, onCleanup, onMount, useContext } from "solid-js";
|
|
4
|
+
|
|
5
|
+
//#region src/lib/context.ts
|
|
6
|
+
const SpookyContext = createContext();
|
|
7
|
+
function useDb() {
|
|
8
|
+
const db = useContext(SpookyContext);
|
|
9
|
+
if (!db) throw new Error("useDb must be used within a <SpookyProvider>. Wrap your app in <SpookyProvider config={...}>.");
|
|
10
|
+
return db;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/lib/use-query.ts
|
|
15
|
+
function useQuery(dbOrQuery, queryOrOptions, maybeOptions) {
|
|
16
|
+
let db;
|
|
17
|
+
let finalQuery;
|
|
18
|
+
let options;
|
|
19
|
+
if (dbOrQuery instanceof SyncedDb) {
|
|
20
|
+
db = dbOrQuery;
|
|
21
|
+
finalQuery = queryOrOptions;
|
|
22
|
+
options = maybeOptions;
|
|
23
|
+
} else {
|
|
24
|
+
const contextDb = useContext(SpookyContext);
|
|
25
|
+
if (!contextDb) throw new Error("useQuery: No db argument provided and no SpookyContext found. Either pass a SyncedDb instance or wrap your app in <SpookyProvider>.");
|
|
26
|
+
db = contextDb;
|
|
27
|
+
finalQuery = dbOrQuery;
|
|
28
|
+
options = queryOrOptions;
|
|
29
|
+
}
|
|
30
|
+
const [data, setData] = createSignal(void 0);
|
|
31
|
+
const [error, setError] = createSignal(void 0);
|
|
32
|
+
const [isFetched, setIsFetched] = createSignal(false);
|
|
33
|
+
const [unsubscribe, setUnsubscribe] = createSignal(void 0);
|
|
34
|
+
let prevQueryString;
|
|
35
|
+
const spooky = db.getSpooky();
|
|
36
|
+
const initQuery = async (query) => {
|
|
37
|
+
const { hash } = await query.run();
|
|
38
|
+
setError(void 0);
|
|
39
|
+
const unsub = await spooky.subscribe(hash, (e) => {
|
|
40
|
+
const data = query.isOne ? e[0] : e;
|
|
41
|
+
setData(() => data);
|
|
42
|
+
setIsFetched(true);
|
|
43
|
+
}, { immediate: true });
|
|
44
|
+
setUnsubscribe(() => unsub);
|
|
45
|
+
};
|
|
46
|
+
createEffect(() => {
|
|
47
|
+
if (!(options?.enabled?.() ?? true)) {
|
|
48
|
+
setError(void 0);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const query = typeof finalQuery === "function" ? finalQuery() : finalQuery;
|
|
52
|
+
if (!query) return;
|
|
53
|
+
const queryString = JSON.stringify(query);
|
|
54
|
+
if (queryString === prevQueryString) return;
|
|
55
|
+
prevQueryString = queryString;
|
|
56
|
+
setIsFetched(false);
|
|
57
|
+
initQuery(query);
|
|
58
|
+
onCleanup(() => {
|
|
59
|
+
unsubscribe?.();
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
const isLoading = () => {
|
|
63
|
+
return !isFetched() && error() === void 0;
|
|
64
|
+
};
|
|
65
|
+
return {
|
|
66
|
+
data,
|
|
67
|
+
error,
|
|
68
|
+
isLoading
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region src/lib/SpookyProvider.ts
|
|
74
|
+
function SpookyProvider(props) {
|
|
75
|
+
const merged = mergeProps({ fallback: void 0 }, props);
|
|
76
|
+
const [db, setDb] = createSignal(void 0);
|
|
77
|
+
onMount(async () => {
|
|
78
|
+
try {
|
|
79
|
+
const instance = new SyncedDb(merged.config);
|
|
80
|
+
await instance.init();
|
|
81
|
+
setDb(() => instance);
|
|
82
|
+
merged.onReady?.(instance);
|
|
83
|
+
} catch (e) {
|
|
84
|
+
const error = e instanceof Error ? e : new Error(String(e));
|
|
85
|
+
if (merged.onError) merged.onError(error);
|
|
86
|
+
else console.error("SpookyProvider: Failed to initialize database", error);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
return createMemo(() => {
|
|
90
|
+
const instance = db();
|
|
91
|
+
if (!instance) return merged.fallback;
|
|
92
|
+
return createComponent(SpookyContext.Provider, {
|
|
93
|
+
value: instance,
|
|
94
|
+
get children() {
|
|
95
|
+
return merged.children;
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
//#endregion
|
|
102
|
+
//#region src/index.ts
|
|
103
|
+
/**
|
|
104
|
+
* SyncedDb - A thin wrapper around spooky-ts for Solid.js integration
|
|
105
|
+
* Delegates all logic to the underlying spooky-ts instance
|
|
106
|
+
*/
|
|
107
|
+
var SyncedDb = class {
|
|
108
|
+
constructor(config) {
|
|
109
|
+
this.spooky = null;
|
|
110
|
+
this._initialized = false;
|
|
111
|
+
this.config = config;
|
|
112
|
+
}
|
|
113
|
+
getSpooky() {
|
|
114
|
+
if (!this.spooky) throw new Error("SyncedDb not initialized");
|
|
115
|
+
return this.spooky;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Initialize the spooky-ts instance
|
|
119
|
+
*/
|
|
120
|
+
async init() {
|
|
121
|
+
if (this._initialized) return;
|
|
122
|
+
this.spooky = new SpookyClient(this.config);
|
|
123
|
+
await this.spooky.init();
|
|
124
|
+
this._initialized = true;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Create a new record in the database
|
|
128
|
+
*/
|
|
129
|
+
async create(id, payload) {
|
|
130
|
+
if (!this.spooky) throw new Error("SyncedDb not initialized");
|
|
131
|
+
await this.spooky.create(id, payload);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Update an existing record in the database
|
|
135
|
+
*/
|
|
136
|
+
async update(tableName, recordId, payload, options) {
|
|
137
|
+
if (!this.spooky) throw new Error("SyncedDb not initialized");
|
|
138
|
+
await this.spooky.update(tableName, recordId, payload, options);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Delete an existing record in the database
|
|
142
|
+
*/
|
|
143
|
+
async delete(tableName, selector) {
|
|
144
|
+
if (!this.spooky) throw new Error("SyncedDb not initialized");
|
|
145
|
+
if (typeof selector !== "string") throw new Error("Only string ID selectors are supported currently with core");
|
|
146
|
+
await this.spooky.delete(tableName, selector);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Query data from the database
|
|
150
|
+
*/
|
|
151
|
+
query(table) {
|
|
152
|
+
if (!this.spooky) throw new Error("SyncedDb not initialized");
|
|
153
|
+
return this.spooky.query(table, {});
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Run a backend operation
|
|
157
|
+
*/
|
|
158
|
+
async run(backend, path, payload, options) {
|
|
159
|
+
if (!this.spooky) throw new Error("SyncedDb not initialized");
|
|
160
|
+
await this.spooky.run(backend, path, payload, options);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Authenticate with the database
|
|
164
|
+
*/
|
|
165
|
+
async authenticate(token) {
|
|
166
|
+
await this.spooky?.authenticate(token);
|
|
167
|
+
return new RecordId("user", "me");
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Deauthenticate from the database
|
|
171
|
+
* @deprecated Use signOut() instead
|
|
172
|
+
*/
|
|
173
|
+
async deauthenticate() {
|
|
174
|
+
await this.signOut();
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Sign out, clear session and local storage
|
|
178
|
+
*/
|
|
179
|
+
async signOut() {
|
|
180
|
+
if (!this.spooky) throw new Error("SyncedDb not initialized");
|
|
181
|
+
await this.spooky.auth.signOut();
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Execute a function with direct access to the remote database connection
|
|
185
|
+
*/
|
|
186
|
+
async useRemote(fn) {
|
|
187
|
+
if (!this.spooky) throw new Error("SyncedDb not initialized");
|
|
188
|
+
return await this.spooky.useRemote(fn);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Access the remote database service directly
|
|
192
|
+
*/
|
|
193
|
+
get remote() {
|
|
194
|
+
if (!this.spooky) throw new Error("SyncedDb not initialized");
|
|
195
|
+
return this.spooky.remoteClient;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Access the local database service directly
|
|
199
|
+
*/
|
|
200
|
+
get local() {
|
|
201
|
+
if (!this.spooky) throw new Error("SyncedDb not initialized");
|
|
202
|
+
return this.spooky.localClient;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Access the auth service
|
|
206
|
+
*/
|
|
207
|
+
get auth() {
|
|
208
|
+
if (!this.spooky) throw new Error("SyncedDb not initialized");
|
|
209
|
+
return this.spooky.auth;
|
|
210
|
+
}
|
|
211
|
+
get pendingMutationCount() {
|
|
212
|
+
if (!this.spooky) throw new Error("SyncedDb not initialized");
|
|
213
|
+
return this.spooky.pendingMutationCount;
|
|
214
|
+
}
|
|
215
|
+
subscribeToPendingMutations(cb) {
|
|
216
|
+
if (!this.spooky) throw new Error("SyncedDb not initialized");
|
|
217
|
+
return this.spooky.subscribeToPendingMutations(cb);
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
//#endregion
|
|
222
|
+
export { RecordId, SpookyProvider, SyncedDb, Uuid, useDb, useQuery };
|
|
223
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/lib/context.ts","../src/lib/use-query.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 const unsub = await spooky.subscribe(\n hash,\n (e) => {\n const data = (query.isOne ? e[0] : e) as TData;\n setData(() => data);\n setIsFetched(true);\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, 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 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} 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 { 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\nexport * from './types';\n"],"mappings":"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"}
|