@arcote.tech/arc-react 0.0.32 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,4 @@
1
- import { type ArcObjectAny, type ArcObjectKeys, type ArcObjectValueByKey } from "@arcote.tech/arc";
2
- import type { ArcAbstractAny } from "@arcote.tech/arc/elements/abstract";
1
+ import type { ArcElement } from "@arcote.tech/arc/elements/element";
3
2
  import React from "react";
4
3
  export type FormFieldContext = {
5
4
  errors: any;
@@ -7,18 +6,18 @@ export type FormFieldContext = {
7
6
  };
8
7
  export declare const FormFieldContext: React.Context<FormFieldContext | null>;
9
8
  export declare function useFormField(): FormFieldContext;
10
- type Translations<E extends ArcAbstractAny> = {
11
- [K in keyof ReturnType<E["validate"]>]: (data: Exclude<ReturnType<E["validate"]>[K], undefined>) => string;
12
- };
13
- type FormFieldProps<T extends ArcObjectAny, K extends ArcObjectKeys<T>> = {
14
- name: K;
15
- translations: Translations<ArcObjectValueByKey<T, K>>;
16
- render: (field: FormFieldData<T>) => React.ReactNode;
9
+ type Translations<E extends ArcElement> = {
10
+ [K in keyof Exclude<ReturnType<E["validate"]>, false>]: (data: Exclude<Exclude<ReturnType<E["validate"]>, false>[K], undefined | false>) => string;
11
+ } | ((data: any) => string) | string;
12
+ type FormFieldProps<E extends ArcElement> = {
13
+ translations: Translations<E>;
14
+ render: (field: FormFieldData<E>) => React.ReactNode;
17
15
  };
18
16
  export type FormFieldData<T> = {
19
17
  onChange: (value: any) => void;
20
18
  value: any;
19
+ name: string;
21
20
  };
22
- export declare function FormField<T extends ArcObjectAny, K extends ArcObjectKeys<T>>({ name, translations, render, }: FormFieldProps<T, K>): import("react/jsx-dev-runtime").JSX.Element;
21
+ export declare function FormField<E extends ArcElement>(name: string): ({ translations, render }: FormFieldProps<E>) => import("react/jsx-dev-runtime").JSX.Element;
23
22
  export {};
24
23
  //# sourceMappingURL=field.d.ts.map
@@ -1,4 +1,4 @@
1
- import { type ArcObjectAny, type ArcObjectKeys } from "@arcote.tech/arc";
1
+ import { type ArcObjectAny, type ArcObjectKeys, type ArcObjectValueByKey } from "@arcote.tech/arc";
2
2
  import React from "react";
3
3
  import { FormField } from "./field";
4
4
  export type FormContextValue<T extends ArcObjectAny> = {
@@ -12,7 +12,7 @@ export type FormContextValue<T extends ArcObjectAny> = {
12
12
  export declare const FormContext: React.Context<FormContextValue<any> | null>;
13
13
  export declare function Form<T extends ArcObjectAny>({ render, schema, onSubmit, }: {
14
14
  render: (props: {
15
- FormField: typeof FormField<T, ArcObjectKeys<T>>;
15
+ [K in ArcObjectKeys<T> as Capitalize<`${K}`>]: ReturnType<typeof FormField<ArcObjectValueByKey<T, K>>>;
16
16
  }) => React.ReactNode;
17
17
  schema: T;
18
18
  onSubmit: (values: Record<ArcObjectKeys<T>, any>) => void | Promise<void>;
@@ -2,5 +2,4 @@ export * from "./field";
2
2
  export * from "./form";
3
3
  export * from "./legacy_form_resolver";
4
4
  export * from "./message";
5
- export * from "./test";
6
5
  //# sourceMappingURL=index.d.ts.map
@@ -1,3 +1,6 @@
1
- import React from "react";
2
- export declare const FormMessage: React.ForwardRefExoticComponent<React.RefAttributes<HTMLDivElement>>;
1
+ import { type HTMLAttributes } from "react";
2
+ export declare function FormMessage({ ...props }: HTMLAttributes<HTMLSpanElement>): import("react/jsx-dev-runtime").JSX.Element | null;
3
+ export declare namespace FormMessage {
4
+ var displayName: string;
5
+ }
3
6
  //# sourceMappingURL=message.d.ts.map
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
1
  export * from "./form/";
2
- export * from "./idb.ts";
3
2
  export * from "./reactModel.tsx";
4
3
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -11,7 +11,6 @@ import {
11
11
  useState
12
12
  } from "react";
13
13
  import { jsx } from "react/jsx-runtime";
14
- "use client";
15
14
  var FormContext = createContext(null);
16
15
  function Form({
17
16
  render,
@@ -23,7 +22,6 @@ function Form({
23
22
  const [dirty, setDirty] = useState(new Set);
24
23
  const [isSubmitted, setIsSubmitted] = useState(false);
25
24
  const validate = useCallback(() => {
26
- console.log("validate", values, schema);
27
25
  const errors2 = schema.validate(values);
28
26
  setErrors(errors2);
29
27
  return Object.values(errors2).some((result) => result);
@@ -43,12 +41,17 @@ function Form({
43
41
  const handleSubmit = useCallback(async (e) => {
44
42
  e.preventDefault();
45
43
  setIsSubmitted(true);
46
- validate();
47
- if (!hasErrors) {
44
+ const hasErrors2 = validate();
45
+ if (!hasErrors2) {
48
46
  await onSubmit(values);
49
47
  }
50
48
  }, [schema, values, onSubmit, hasErrors]);
51
- const FF = useCallback(FormField, []);
49
+ const Fields = useMemo(() => {
50
+ return Object.fromEntries(schema.entries().map(([key, value]) => [
51
+ key.charAt(0).toUpperCase() + key.slice(1),
52
+ FormField(key)
53
+ ]));
54
+ }, [schema]);
52
55
  const contextValue = useMemo(() => ({
53
56
  values,
54
57
  errors,
@@ -61,7 +64,7 @@ function Form({
61
64
  value: contextValue,
62
65
  children: /* @__PURE__ */ jsx("form", {
63
66
  onSubmit: handleSubmit,
64
- children: render({ FormField: FF })
67
+ children: render(Fields)
65
68
  }, undefined, false, undefined, this)
66
69
  }, undefined, false, undefined, this);
67
70
  }
@@ -69,7 +72,6 @@ Form.displayName = "Form";
69
72
 
70
73
  // form/field.tsx
71
74
  import { jsx as jsx2 } from "react/jsx-runtime";
72
- "use client";
73
75
  var FormFieldContext = createContext2(null);
74
76
  function useFormField() {
75
77
  const context = useContext(FormFieldContext);
@@ -77,45 +79,52 @@ function useFormField() {
77
79
  throw new Error("useFormField must be used within a FormFieldProvider");
78
80
  return context;
79
81
  }
80
- function FormField({
81
- name,
82
- translations,
83
- render
84
- }) {
85
- const form = useContext(FormContext);
86
- if (!form)
87
- throw new Error("FormField must be used within a Form");
88
- const { values, errors, dirty, isSubmitted, setFieldValue, setFieldDirty } = form;
89
- const fieldErrors = errors[name] || {};
90
- const value = values[name] || "";
91
- const isDirty = dirty.has(name);
92
- const handleChange = useCallback2((value2) => {
93
- if (typeof value2 === "string") {
94
- setFieldValue(name, value2);
95
- } else if (value2?.target?.value !== undefined) {
96
- setFieldValue(name, value2.target.value);
97
- }
98
- if (!isDirty) {
99
- setFieldDirty(name);
100
- }
101
- }, [name, isDirty, setFieldValue, setFieldDirty]);
102
- const errorMessages = Object.entries(fieldErrors).map(([key, value2]) => {
103
- if (!value2)
104
- return;
105
- const translation = translations[key];
106
- return translation?.(value2);
107
- }).filter(Boolean);
108
- const contextValue = useMemo2(() => ({
109
- errors: isSubmitted ? fieldErrors : {},
110
- messages: errorMessages
111
- }), [fieldErrors, isSubmitted, errorMessages]);
112
- return /* @__PURE__ */ jsx2(FormFieldContext.Provider, {
113
- value: contextValue,
114
- children: render({
115
- onChange: handleChange,
116
- value
117
- })
118
- }, undefined, false, undefined, this);
82
+ function FormField(name) {
83
+ return ({ translations, render }) => {
84
+ const form = useContext(FormContext);
85
+ if (!form)
86
+ throw new Error("FormField must be used within a Form");
87
+ const { values, errors, dirty, isSubmitted, setFieldValue, setFieldDirty } = form;
88
+ const schemaErrors = errors?.["schema"] || {};
89
+ const fieldErrors = schemaErrors[name] || false;
90
+ const value = values[name] || "";
91
+ const isDirty = dirty.has(name);
92
+ const handleChange = useCallback2((value2) => {
93
+ if (typeof value2 === "string") {
94
+ setFieldValue(name, value2);
95
+ } else if (value2?.target?.value !== undefined) {
96
+ setFieldValue(name, value2.target.value);
97
+ }
98
+ if (!isDirty) {
99
+ setFieldDirty(name);
100
+ }
101
+ }, [name, isDirty, setFieldValue, setFieldDirty]);
102
+ const errorMessages = fieldErrors ? Object.entries(fieldErrors).map(([key, value2]) => {
103
+ if (!value2)
104
+ return;
105
+ if (!translations)
106
+ return;
107
+ const translation = translations[key] || translations;
108
+ if (typeof translation === "function") {
109
+ return translation(value2);
110
+ }
111
+ if (typeof translation === "string") {
112
+ return translation;
113
+ }
114
+ }).filter(Boolean) : [];
115
+ const contextValue = useMemo2(() => ({
116
+ errors: isSubmitted ? fieldErrors : false,
117
+ messages: errorMessages
118
+ }), [fieldErrors, isSubmitted, errorMessages]);
119
+ return /* @__PURE__ */ jsx2(FormFieldContext.Provider, {
120
+ value: contextValue,
121
+ children: render({
122
+ onChange: handleChange,
123
+ name: name.toString(),
124
+ value
125
+ })
126
+ }, undefined, false, undefined, this);
127
+ };
119
128
  }
120
129
  // form/legacy_form_resolver.ts
121
130
  function formResolver(schema) {
@@ -127,216 +136,22 @@ function formResolver(schema) {
127
136
  };
128
137
  }
129
138
  // form/message.tsx
130
- import React3 from "react";
131
139
  import { jsx as jsx3 } from "react/jsx-runtime";
132
- "use client";
133
- var FormMessage = React3.forwardRef(({}, ref) => {
140
+ function FormMessage({ ...props }) {
134
141
  const { messages } = useFormField();
135
142
  if (messages.length === 0)
136
143
  return null;
137
- return /* @__PURE__ */ jsx3("div", {
138
- className: "text-destructive",
139
- ref,
144
+ return /* @__PURE__ */ jsx3("span", {
145
+ ...props,
140
146
  children: messages[0]
141
147
  }, undefined, false, undefined, this);
142
- });
143
- FormMessage.displayName = "FormMessage";
144
- // form/test.tsx
145
- import { object, string } from "@arcote.tech/arc";
146
- import { jsx as jsx4, Fragment } from "react/jsx-runtime";
147
- "use client";
148
- function Test() {
149
- const schema = object({
150
- username: string().minLength(3).maxLength(10)
151
- });
152
- const handleSubmit = async (values) => {
153
- console.log("Form submitted:", values);
154
- };
155
- return /* @__PURE__ */ jsx4(Form, {
156
- schema,
157
- onSubmit: handleSubmit,
158
- render: ({ FormField: FormField2 }) => /* @__PURE__ */ jsx4("div", {
159
- children: [
160
- /* @__PURE__ */ jsx4(FormField2, {
161
- name: "username",
162
- translations: {
163
- minLength: ({ minLength }) => `Username must be at least ${minLength} characters long`,
164
- maxLength: ({ maxLength }) => `Username must be at most ${maxLength} characters long`
165
- },
166
- render: (field) => /* @__PURE__ */ jsx4(Fragment, {
167
- children: [
168
- /* @__PURE__ */ jsx4("input", {
169
- className: "border border-gray-300 rounded-md p-2",
170
- ...field
171
- }, undefined, false, undefined, this),
172
- /* @__PURE__ */ jsx4(FormMessage, {}, undefined, false, undefined, this)
173
- ]
174
- }, undefined, true, undefined, this)
175
- }, undefined, false, undefined, this),
176
- /* @__PURE__ */ jsx4("button", {
177
- type: "submit",
178
- children: "Submit"
179
- }, undefined, false, undefined, this)
180
- ]
181
- }, undefined, true, undefined, this)
182
- }, undefined, false, undefined, this);
183
- }
184
- // idb.ts
185
- import {
186
- ArcCollection,
187
- ArcIndexedCollection
188
- } from "@arcote.tech/arc";
189
- var idbAdapterFactory = (name, version) => (context) => new Promise((resolve, reject) => {
190
- const dbRequest = indexedDB.open(name, version);
191
- dbRequest.addEventListener("error", (err) => {
192
- reject(err);
193
- });
194
- dbRequest.addEventListener("success", (ev) => {
195
- resolve(new IDBAdapter(ev.target.result));
196
- });
197
- dbRequest.addEventListener("upgradeneeded", (ev) => {
198
- const db = ev.target.result;
199
- context.elements.filter((element) => element instanceof ArcIndexedCollection || element instanceof ArcCollection).forEach((collection) => {
200
- const name2 = collection.name;
201
- if (db.objectStoreNames.contains(name2)) {
202
- db.deleteObjectStore(collection.name);
203
- }
204
- const objectStore = db.createObjectStore(collection.name, {
205
- keyPath: "_id"
206
- });
207
- if (collection instanceof ArcIndexedCollection) {
208
- Object.entries(collection.indexes).forEach(([name3, keyPath]) => {
209
- objectStore.createIndex(name3, keyPath, {
210
- unique: false
211
- });
212
- });
213
- }
214
- });
215
- if (db.objectStoreNames.contains("state")) {
216
- db.deleteObjectStore("state");
217
- }
218
- db.createObjectStore("state", {
219
- keyPath: "_id"
220
- });
221
- });
222
- });
223
-
224
- class IDBReadTransaction {
225
- transaction;
226
- constructor(transaction) {
227
- this.transaction = transaction;
228
- }
229
- async findById(store, id) {
230
- return new Promise((resolve) => {
231
- if (!id) {
232
- resolve(undefined);
233
- return;
234
- }
235
- const result = this.transaction.objectStore(store).get(id);
236
- result.onsuccess = (e) => {
237
- resolve(e.target.result);
238
- };
239
- });
240
- }
241
- async findByIndex(store, index, data) {
242
- return new Promise((resolve) => {
243
- const idbIndex = this.transaction.objectStore(store).index(index);
244
- const keyPath = idbIndex.keyPath;
245
- let keyRange;
246
- const getKey = (obj) => {
247
- if (!obj)
248
- return;
249
- const key = keyPath.map((key2) => obj[key2]);
250
- if (key.some((value) => value === undefined))
251
- return;
252
- return key;
253
- };
254
- const simpleKey = getKey(data);
255
- if (!simpleKey) {
256
- const lower = "$gt" in data ? getKey(data.$gt) : getKey(data.$gte);
257
- const upper = "$lt" in data ? getKey(data.$lt) : getKey(data.$lte);
258
- const lowerOpen = "$gt" in data;
259
- const upperOpen = "$lt" in data;
260
- if (lower !== undefined && upper !== undefined) {
261
- keyRange = IDBKeyRange.bound(lower, upper, lowerOpen, upperOpen);
262
- } else if (lower !== undefined) {
263
- keyRange = IDBKeyRange.lowerBound(lower, lowerOpen);
264
- } else {
265
- keyRange = IDBKeyRange.upperBound(upper, upperOpen);
266
- }
267
- } else {
268
- keyRange = IDBKeyRange.only(simpleKey);
269
- }
270
- const result = idbIndex.getAll(keyRange);
271
- result.onsuccess = (e) => {
272
- resolve(e.target.result);
273
- };
274
- });
275
- }
276
- async findAll(store) {
277
- return new Promise((resolve) => {
278
- const result = this.transaction.objectStore(store).getAll();
279
- result.onsuccess = (e) => {
280
- resolve(e.target.result);
281
- };
282
- });
283
- }
284
- }
285
-
286
- class IDBReadWriteTransaction extends IDBReadTransaction {
287
- async set(store, data) {
288
- return new Promise((resolve, reject) => {
289
- const result = this.transaction.objectStore(store).put(data);
290
- result.onsuccess = (e) => {
291
- resolve();
292
- };
293
- result.onerror = (e) => {
294
- reject(e);
295
- };
296
- });
297
- }
298
- async remove(store, id) {
299
- return new Promise((resolve, reject) => {
300
- const result = this.transaction.objectStore(store).delete(id);
301
- result.onsuccess = (e) => {
302
- resolve();
303
- };
304
- result.onerror = (e) => {
305
- reject(e);
306
- };
307
- });
308
- }
309
- async commit() {
310
- return new Promise((resolve) => {
311
- this.transaction.oncomplete = () => {
312
- resolve();
313
- };
314
- this.transaction.commit();
315
- });
316
- }
317
- }
318
-
319
- class IDBAdapter {
320
- db;
321
- constructor(db) {
322
- this.db = db;
323
- }
324
- readWriteTransaction(stores) {
325
- if (!stores)
326
- stores = Array.from(this.db.objectStoreNames);
327
- const transaction = this.db.transaction(stores, "readwrite");
328
- return new IDBReadWriteTransaction(transaction);
329
- }
330
- readTransaction(stores) {
331
- if (!stores)
332
- stores = Array.from(this.db.objectStoreNames);
333
- const transaction = this.db.transaction(stores, "readonly");
334
- return new IDBReadTransaction(transaction);
335
- }
336
148
  }
149
+ FormMessage.displayName = "FormMessage";
337
150
  // reactModel.tsx
338
151
  import {
339
152
  MasterDataStorage,
153
+ Model,
154
+ RemoteModelClient,
340
155
  rtcClientFactory
341
156
  } from "@arcote.tech/arc";
342
157
  import {
@@ -347,127 +162,133 @@ import {
347
162
  useRef,
348
163
  useState as useState2
349
164
  } from "react";
350
- import { jsx as jsx5 } from "react/jsx-runtime";
351
- "use client";
352
- var reactModel = (arcContext, databaseName) => {
165
+
166
+ // sqliteWasmAdapter.ts
167
+ import {
168
+ createSQLiteAdapterFactory
169
+ } from "@arcote.tech/arc";
170
+ var sqliteWasmAdapterFactory = (db) => {
171
+ return async (context) => {
172
+ return createSQLiteAdapterFactory(db)(context);
173
+ };
174
+ };
175
+
176
+ // reactModel.tsx
177
+ import { jsx as jsx4 } from "react/jsx-runtime";
178
+ var reactModel = (arcContext, options) => {
353
179
  const LiveModelContext = createContext3(null);
354
180
  const LocalModelContext = createContext3(null);
355
- let modelMasterDataStorage = null;
181
+ let masterModel = null;
356
182
  return [
357
183
  function LiveModelProvider(props) {
358
- const dataStorage = useMemo3(() => {
184
+ const model = useMemo3(() => {
359
185
  if (typeof window === "undefined")
360
186
  return null;
361
- const dbAdapterPromise = idbAdapterFactory(databaseName, arcContext.version)(arcContext);
362
- const dataStorage2 = new MasterDataStorage(dbAdapterPromise, rtcClientFactory(props.token), arcContext);
363
- modelMasterDataStorage = dataStorage2;
364
- return dataStorage2;
365
- }, [arcContext, databaseName, arcContext.version]);
187
+ if (masterModel)
188
+ return masterModel;
189
+ if ("remoteUrl" in options) {
190
+ const model2 = new RemoteModelClient(arcContext, options.remoteUrl, props.client, props.catchErrorCallback);
191
+ masterModel = model2;
192
+ return model2;
193
+ } else {
194
+ const dbAdapterPromise = sqliteWasmAdapterFactory(options.sqliteAdapter)(arcContext);
195
+ const dataStorage = new MasterDataStorage(dbAdapterPromise, rtcClientFactory(props.token), arcContext);
196
+ const model2 = new Model(arcContext, dataStorage, props.client, props.catchErrorCallback);
197
+ masterModel = model2;
198
+ return model2;
199
+ }
200
+ }, [arcContext, options, props.client]);
366
201
  const [syncProgress, setSyncProgress] = useState2([]);
367
202
  const [syncDone, setSyncDone] = useState2(false);
368
203
  useEffect2(() => {
369
- if (typeof window === "undefined" || !dataStorage)
204
+ if (typeof window === "undefined" || !model)
370
205
  return;
371
206
  const sync = async () => {
372
- await dataStorage.sync(({ store, size }) => {
207
+ if (!("dataStorage" in model))
208
+ return setSyncDone(true);
209
+ await model.dataStorage.sync(({ store, size }) => {
373
210
  setSyncProgress((prev) => [...prev, { store, size }]);
374
211
  });
375
212
  setSyncDone(true);
376
213
  };
377
214
  sync();
378
- }, [dataStorage]);
379
- if (!dataStorage || !syncDone)
380
- return /* @__PURE__ */ jsx5(props.syncView, {
215
+ }, [model]);
216
+ if (!model || !syncDone)
217
+ return props.syncView ? /* @__PURE__ */ jsx4(props.syncView, {
381
218
  progress: syncProgress
382
- }, undefined, false, undefined, this);
383
- return /* @__PURE__ */ jsx5(LiveModelContext.Provider, {
384
- value: {
385
- dataStorage,
386
- client: props.client,
387
- catchErrorCallback: props.catchErrorCallback
388
- },
219
+ }, undefined, false, undefined, this) : null;
220
+ return /* @__PURE__ */ jsx4(LiveModelContext.Provider, {
221
+ value: model,
389
222
  children: props.children
390
223
  }, undefined, false, undefined, this);
391
224
  },
392
225
  function LocalModelProvider({ children }) {
393
- const parentContext = useContext2(LiveModelContext);
394
- if (!parentContext) {
226
+ const parentModel = useContext2(LiveModelContext);
227
+ if (!parentModel || !(parentModel instanceof Model)) {
395
228
  throw new Error("LocalModelProvider must be used within a LiveModelProvider");
396
229
  }
397
- const [localContext] = useState2(() => ({
398
- dataStorage: parentContext.dataStorage.fork()
399
- }));
400
- return /* @__PURE__ */ jsx5(LocalModelContext.Provider, {
401
- value: {
402
- dataStorage: localContext.dataStorage,
403
- client: parentContext.client,
404
- catchErrorCallback: parentContext.catchErrorCallback
405
- },
230
+ const [localModel] = useState2(() => parentModel.fork());
231
+ return /* @__PURE__ */ jsx4(LocalModelContext.Provider, {
232
+ value: localModel,
406
233
  children
407
234
  }, undefined, false, undefined, this);
408
235
  },
409
236
  function useQuery(queryBuilderFn, dependencies = []) {
410
- const context = useContext2(LocalModelContext) || useContext2(LiveModelContext);
411
- if (!context) {
237
+ const model = useContext2(LocalModelContext) || useContext2(LiveModelContext);
238
+ if (!model) {
412
239
  throw new Error("useQuery must be used within a ModelProvider");
413
240
  }
414
241
  const [result, setResult] = useState2(null);
415
242
  const [loading, setLoading] = useState2(true);
416
- const queryRef = useRef(null);
243
+ const unsubscribeRef = useRef(null);
417
244
  useEffect2(() => {
418
- if (queryRef.current)
419
- queryRef.current.unsubscribe();
420
- const queryBuilder = arcContext.queryBuilder();
421
- const query = queryBuilderFn(queryBuilder).toQuery();
422
- queryRef.current = query;
423
- const runQuery = async () => {
424
- const result2 = await query.run(context.dataStorage, (newResult) => {
425
- setResult(newResult);
426
- setLoading(false);
427
- });
428
- setResult(result2);
245
+ if (unsubscribeRef.current) {
246
+ unsubscribeRef.current();
247
+ }
248
+ const { unsubscribe, result: result2 } = model.subscribe(queryBuilderFn, (newResult) => {
249
+ setResult(newResult);
429
250
  setLoading(false);
430
- };
431
- runQuery();
251
+ });
252
+ unsubscribeRef.current = unsubscribe;
253
+ result2.then(() => {
254
+ setLoading(false);
255
+ });
432
256
  return () => {
433
- queryRef.current?.unsubscribe();
434
- queryRef.current = null;
257
+ if (unsubscribeRef.current) {
258
+ unsubscribeRef.current();
259
+ unsubscribeRef.current = null;
260
+ }
435
261
  };
436
- }, [context, ...dependencies]);
262
+ }, [model, ...dependencies]);
437
263
  return [result, loading];
438
264
  },
439
265
  function useCommands() {
440
- const context = useContext2(LocalModelContext) || useContext2(LiveModelContext);
441
- if (!context) {
442
- throw new Error("useQuery must be used within a ModelProvider");
266
+ const model = useContext2(LocalModelContext) || useContext2(LiveModelContext);
267
+ if (!model) {
268
+ throw new Error("useCommands must be used within a ModelProvider");
443
269
  }
444
- return arcContext.commandsClient(context.client, context.dataStorage, context.catchErrorCallback);
270
+ return model.commands();
445
271
  },
446
- async function query(queryBuilderFn, datastorage) {
447
- if (!datastorage)
448
- datastorage = modelMasterDataStorage;
449
- const queryBuilder = arcContext.queryBuilder();
450
- const query = queryBuilderFn(queryBuilder).toQuery();
451
- if (!datastorage)
452
- throw new Error("dataStorage not found");
453
- const result = await query.run(datastorage);
454
- return result;
272
+ async function query(queryBuilderFn, model) {
273
+ if (!model)
274
+ model = masterModel;
275
+ if (!model)
276
+ throw new Error("Model not found");
277
+ return model.query(queryBuilderFn);
455
278
  },
456
- function useLocalDataStorage() {
457
- const context = useContext2(LocalModelContext);
458
- if (!context) {
279
+ function useLocalModel() {
280
+ const model = useContext2(LocalModelContext);
281
+ if (!model) {
459
282
  return null;
460
283
  }
461
- return context.dataStorage;
284
+ return model;
462
285
  }
463
286
  ];
464
287
  };
465
288
  export {
466
289
  useFormField,
467
290
  reactModel,
468
- idbAdapterFactory,
469
291
  formResolver,
470
- Test,
471
292
  FormMessage,
472
293
  FormFieldContext,
473
294
  FormField,
@@ -475,4 +296,4 @@ export {
475
296
  Form
476
297
  };
477
298
 
478
- //# debugId=1DDD66A12E066C4464756E2164756E21
299
+ //# debugId=F5FEB20267C5EE2264756E2164756E21
@@ -1,16 +1,21 @@
1
- import { ForkedDataStorage, type ArcContextAny, type CommandsClient, type DataStorage, type QueryBuilderFunctionResult, type QueryFactoryFunction } from "@arcote.tech/arc";
2
- export declare const reactModel: <C extends ArcContextAny>(arcContext: C, databaseName: string) => readonly [(props: {
1
+ import { ForkedModel, type ArcContextAny, type IArcQueryBuilder, type ModelBase, type QueryBuilderFunctionResult, type QueryFactoryFunction, type UnaryFunction } from "@arcote.tech/arc";
2
+ import type { SQLiteDatabase } from "@arcote.tech/arc";
3
+ export declare const reactModel: <C extends ArcContextAny>(arcContext: C, options: {
4
+ sqliteAdapter: SQLiteDatabase;
5
+ } | {
6
+ remoteUrl: string;
7
+ }) => readonly [(props: {
3
8
  children: React.ReactNode;
4
9
  client: string;
5
10
  token: string;
6
- syncView: React.ComponentType<{
11
+ syncView?: React.ComponentType<{
7
12
  progress: {
8
13
  store: string;
9
14
  size: number;
10
15
  }[];
11
16
  }>;
12
17
  catchErrorCallback: (error: any) => void;
13
- }) => import("react/jsx-dev-runtime").JSX.Element, ({ children }: {
18
+ }) => import("react/jsx-dev-runtime").JSX.Element | null, ({ children }: {
14
19
  children: React.ReactNode;
15
- }) => import("react/jsx-dev-runtime").JSX.Element, <QueryBuilderFn extends QueryFactoryFunction<C>>(queryBuilderFn: QueryBuilderFn, dependencies?: any[]) => [QueryBuilderFunctionResult<QueryBuilderFn>, boolean], () => CommandsClient<C["commands"]>, <QueryBuilderFn extends QueryFactoryFunction<C>>(queryBuilderFn: QueryBuilderFn, datastorage?: DataStorage | null) => Promise<QueryBuilderFunctionResult<QueryBuilderFn>>, () => ForkedDataStorage | null];
20
+ }) => import("react/jsx-dev-runtime").JSX.Element, <Q extends IArcQueryBuilder>(queryBuilderFn: UnaryFunction<ReturnType<C["queryBuilder"]>, Q>, dependencies?: any[]) => [ReturnType<Q["toQuery"]>["lastResult"], boolean], () => ReturnType<C["commandsClient"]>, <QueryBuilderFn extends QueryFactoryFunction<C>>(queryBuilderFn: QueryBuilderFn, model?: ModelBase<C> | null) => Promise<QueryBuilderFunctionResult<QueryBuilderFn>>, () => ForkedModel<C> | null];
16
21
  //# sourceMappingURL=reactModel.d.ts.map
@@ -0,0 +1,4 @@
1
+ import type { SQLiteDatabase } from "@arcote.tech/arc";
2
+ import { type DBAdapterFactory } from "@arcote.tech/arc";
3
+ export declare const sqliteWasmAdapterFactory: (db: SQLiteDatabase) => DBAdapterFactory;
4
+ //# sourceMappingURL=sqliteWasmAdapter.d.ts.map
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
7
- "version": "0.0.32",
7
+ "version": "0.1.0",
8
8
  "private": false,
9
9
  "author": "Przemysław Krasiński [arcote.tech]",
10
10
  "description": "React client for the Arc framework, providing utilities for querying data and executing commands, enhancing the development of reactive and efficient user interfaces.",
@@ -1,2 +0,0 @@
1
- export declare function Test(): import("react/jsx-dev-runtime").JSX.Element;
2
- //# sourceMappingURL=test.d.ts.map
package/dist/idb.d.ts DELETED
@@ -1,3 +0,0 @@
1
- import { type DBAdapterFactory } from "@arcote.tech/arc";
2
- export declare const idbAdapterFactory: (name: string, version: number) => DBAdapterFactory;
3
- //# sourceMappingURL=idb.d.ts.map