@pol-studios/db 1.0.31 → 1.0.34

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.
Files changed (107) hide show
  1. package/dist/{DataLayerContext-Dc7nF2IG.d.ts → DataLayerContext-BwMk4VpG.d.ts} +92 -8
  2. package/dist/UserMetadataContext-QLIv-mfF.d.ts +171 -0
  3. package/dist/{UserMetadataContext-B8gVWGMl.d.ts → UserMetadataContext-pQb3A8_Q.d.ts} +1 -1
  4. package/dist/auth/context.d.ts +53 -5
  5. package/dist/auth/context.js +30 -8
  6. package/dist/auth/guards.d.ts +9 -9
  7. package/dist/auth/guards.js +2 -3
  8. package/dist/auth/hooks.d.ts +108 -4
  9. package/dist/auth/hooks.js +13 -9
  10. package/dist/auth/index.d.ts +6 -6
  11. package/dist/auth/index.js +45 -17
  12. package/dist/chunk-5HJLTYRA.js +355 -0
  13. package/dist/chunk-5HJLTYRA.js.map +1 -0
  14. package/dist/{chunk-WX4ABYIF.js → chunk-67HMVGV7.js} +292 -94
  15. package/dist/chunk-67HMVGV7.js.map +1 -0
  16. package/dist/chunk-6KN7KLEG.js +1 -0
  17. package/dist/{chunk-FZF26ZRB.js → chunk-7BGDQT5X.js} +29 -16
  18. package/dist/{chunk-FZF26ZRB.js.map → chunk-7BGDQT5X.js.map} +1 -1
  19. package/dist/{chunk-P4UZ7IXC.js → chunk-7D4SUZUM.js} +1 -5
  20. package/dist/{chunk-3PJTNH2L.js → chunk-AKIRHA4Q.js} +2 -2
  21. package/dist/{chunk-OQ7U6EQ3.js → chunk-AML2TLXJ.js} +3801 -3424
  22. package/dist/chunk-AML2TLXJ.js.map +1 -0
  23. package/dist/{chunk-5EFDS7SR.js → chunk-DMVUEJG2.js} +7 -2
  24. package/dist/chunk-DMVUEJG2.js.map +1 -0
  25. package/dist/{chunk-ADD5MIMK.js → chunk-FESQS4S5.js} +15 -15
  26. package/dist/{chunk-ADD5MIMK.js.map → chunk-FESQS4S5.js.map} +1 -1
  27. package/dist/{chunk-U5UNPBKB.js → chunk-FI6JAD5G.js} +3 -3
  28. package/dist/{chunk-TKWR5AAY.js → chunk-JOULSXOI.js} +2 -2
  29. package/dist/{chunk-HTJ2FQW5.js → chunk-LF3V3ERS.js} +13 -15
  30. package/dist/{chunk-HTJ2FQW5.js.map → chunk-LF3V3ERS.js.map} +1 -1
  31. package/dist/{chunk-5BLKZUKM.js → chunk-MREERKQU.js} +45 -14
  32. package/dist/chunk-MREERKQU.js.map +1 -0
  33. package/dist/{chunk-VGEMLNNM.js → chunk-NP34C3O3.js} +306 -704
  34. package/dist/chunk-NP34C3O3.js.map +1 -0
  35. package/dist/{chunk-CNIGRBRE.js → chunk-QJZUIAHA.js} +43 -19
  36. package/dist/{chunk-CNIGRBRE.js.map → chunk-QJZUIAHA.js.map} +1 -1
  37. package/dist/{chunk-HAWJTZCK.js → chunk-RT4O5H2E.js} +5 -7
  38. package/dist/chunk-RT4O5H2E.js.map +1 -0
  39. package/dist/{chunk-2NVSXZKQ.js → chunk-TN7QINPK.js} +74 -309
  40. package/dist/chunk-TN7QINPK.js.map +1 -0
  41. package/dist/chunk-UBHORKBS.js +215 -0
  42. package/dist/chunk-UBHORKBS.js.map +1 -0
  43. package/dist/{chunk-WVF7RUW5.js → chunk-WM25QE7E.js} +3 -3
  44. package/dist/{chunk-H6365JPC.js → chunk-YUX6RGLZ.js} +3 -3
  45. package/dist/{chunk-H6365JPC.js.map → chunk-YUX6RGLZ.js.map} +1 -1
  46. package/dist/{chunk-H3LNH2NT.js → chunk-Z456IHCB.js} +5 -9
  47. package/dist/{chunk-H3LNH2NT.js.map → chunk-Z456IHCB.js.map} +1 -1
  48. package/dist/{chunk-JAATANS3.js → chunk-ZCOFRJQD.js} +3 -3
  49. package/dist/{chunk-JAATANS3.js.map → chunk-ZCOFRJQD.js.map} +1 -1
  50. package/dist/client/index.d.ts +1 -1
  51. package/dist/client/index.js +2 -2
  52. package/dist/core/index.d.ts +54 -31
  53. package/dist/{executor-Br27YZvl.d.ts → executor-YJw4m7Q7.d.ts} +9 -1
  54. package/dist/gen/index.js +1 -1
  55. package/dist/hooks/index.d.ts +3 -22
  56. package/dist/hooks/index.js +12 -9
  57. package/dist/{index-CYFdO0iB.d.ts → index-lveh8qb0.d.ts} +1 -1
  58. package/dist/index.d.ts +38 -10
  59. package/dist/index.js +57 -36
  60. package/dist/index.native.d.ts +19 -13
  61. package/dist/index.native.js +64 -35
  62. package/dist/index.web.d.ts +18 -45
  63. package/dist/index.web.js +58 -49
  64. package/dist/index.web.js.map +1 -1
  65. package/dist/mutation/index.d.ts +2 -2
  66. package/dist/mutation/index.js +5 -5
  67. package/dist/parser/index.js +4 -4
  68. package/dist/powersync-bridge/index.d.ts +18 -3
  69. package/dist/powersync-bridge/index.js +2 -2
  70. package/dist/query/index.d.ts +1 -1
  71. package/dist/query/index.js +7 -8
  72. package/dist/realtime/index.js +7 -9
  73. package/dist/realtime/index.js.map +1 -1
  74. package/dist/types/index.d.ts +3 -3
  75. package/dist/types/index.js +6 -7
  76. package/dist/{useBatchUpsert-9OYjibLh.d.ts → useBatchUpsert-DAkiCNo3.d.ts} +1 -1
  77. package/dist/{useDbCount-Dk0yCKlT.d.ts → useDbCount-DWfYB2iu.d.ts} +16 -2
  78. package/dist/{useResolveFeedback-C1KucfdQ.d.ts → useResolveFeedback-CxLccZKK.d.ts} +197 -93
  79. package/dist/{useSupabase-DvWVuHHE.d.ts → useSupabase-DSZNeXnF.d.ts} +1 -1
  80. package/dist/with-auth/index.d.ts +2 -2
  81. package/dist/with-auth/index.js +46 -33
  82. package/dist/with-auth/index.js.map +1 -1
  83. package/package.json +18 -8
  84. package/dist/UserMetadataContext-DntmpK41.d.ts +0 -33
  85. package/dist/canvas-C4TBBDUL.node +0 -0
  86. package/dist/canvas-ZQNCL7JL.js +0 -1541
  87. package/dist/canvas-ZQNCL7JL.js.map +0 -1
  88. package/dist/chunk-2NVSXZKQ.js.map +0 -1
  89. package/dist/chunk-5BLKZUKM.js.map +0 -1
  90. package/dist/chunk-5EFDS7SR.js.map +0 -1
  91. package/dist/chunk-HAWJTZCK.js.map +0 -1
  92. package/dist/chunk-NSIAAYW3.js +0 -1
  93. package/dist/chunk-O7SETNGD.js +0 -3391
  94. package/dist/chunk-O7SETNGD.js.map +0 -1
  95. package/dist/chunk-OQ7U6EQ3.js.map +0 -1
  96. package/dist/chunk-VGEMLNNM.js.map +0 -1
  97. package/dist/chunk-WX4ABYIF.js.map +0 -1
  98. package/dist/dist-NDNRSNOG.js +0 -521
  99. package/dist/dist-NDNRSNOG.js.map +0 -1
  100. package/dist/pdf-PHXP7RHD.js +0 -20336
  101. package/dist/pdf-PHXP7RHD.js.map +0 -1
  102. /package/dist/{chunk-NSIAAYW3.js.map → chunk-6KN7KLEG.js.map} +0 -0
  103. /package/dist/{chunk-P4UZ7IXC.js.map → chunk-7D4SUZUM.js.map} +0 -0
  104. /package/dist/{chunk-3PJTNH2L.js.map → chunk-AKIRHA4Q.js.map} +0 -0
  105. /package/dist/{chunk-U5UNPBKB.js.map → chunk-FI6JAD5G.js.map} +0 -0
  106. /package/dist/{chunk-TKWR5AAY.js.map → chunk-JOULSXOI.js.map} +0 -0
  107. /package/dist/{chunk-WVF7RUW5.js.map → chunk-WM25QE7E.js.map} +0 -0
@@ -1,4 +1,4 @@
1
- import { p as DataLayerContextValue, q as DataLayerCoreContextValue, r as DataLayerStatusContextValue } from './DataLayerContext-Dc7nF2IG.js';
1
+ import { r as DataLayerContextValue, s as DataLayerCoreContextValue, t as DataLayerStatusContextValue } from './DataLayerContext-BwMk4VpG.js';
2
2
  import { Dispatch, SetStateAction } from 'react';
3
3
  import { QueryOptions, WhereClause } from './core/index.js';
4
4
 
@@ -40,6 +40,20 @@ import { QueryOptions, WhereClause } from './core/index.js';
40
40
  * // This component won't re-render on sync status changes
41
41
  */
42
42
  declare function useDataLayerCore(): DataLayerCoreContextValue;
43
+ /**
44
+ * Hook to access ONLY the STABLE core context (optional version).
45
+ * Returns null if DataLayerProvider is not present, rather than throwing.
46
+ * Use this when you need graceful fallback behavior.
47
+ *
48
+ * @example
49
+ * const dataLayerCore = useDataLayerCoreOptional();
50
+ * if (dataLayerCore) {
51
+ * // Use V3 adapter pattern
52
+ * } else {
53
+ * // Fall back to Supabase
54
+ * }
55
+ */
56
+ declare function useDataLayerCoreOptional(): DataLayerCoreContextValue | null;
43
57
  /**
44
58
  * Hook to access ONLY the dynamic status values
45
59
  *
@@ -1079,4 +1093,4 @@ interface UseDbCountResult {
1079
1093
  */
1080
1094
  declare function useDbCount(table: string, options?: UseDbCountOptions): UseDbCountResult;
1081
1095
 
1082
- export { type Sort as A, type UseDbInsertOptions as B, type ClarificationQuestion as C, type DatabaseTypes$1 as D, type UseDbInsertResult as E, type Filter as F, type UseDbUpdateOptions as G, type UseDbUpdateResult as H, type UseDbUpsertOptions as I, type UseDbUpsertResult as J, type UseDbDeleteOptions as K, type UseDbDeleteResult as L, type PublicTableNames$1 as P, type QueryState as Q, type ResolveRowType$1 as R, type SchemaNames$1 as S, type TableIdentifier$1 as T, type UseAdvanceQueryOptions as U, useDataLayer as a, useDataLayerCore as b, useDataLayerStatus as c, useDbCount as d, useDbDelete as e, useDbInfiniteQuery as f, useDbInsert as g, useDbQuery as h, useDbQueryById as i, useDbUpdate as j, useDbUpsert as k, type SchemaTableNames$1 as l, type UseAdvanceQueryResult as m, type UseDbCountOptions as n, type UseDbCountResult as o, type UseDbInfiniteQueryOptions as p, type UseDbInfiniteQueryResult as q, type UseDbQueryOptions as r, type UseDbQueryResult as s, useDataLayerOptional as t, useAdvanceQuery as u, type UseDbQueryByIdOptions as v, type UseDbQueryByIdResult as w, type FilterGroup as x, type FilterOperator as y, type Pagination as z };
1096
+ export { type Sort as A, type UseDbInsertOptions as B, type ClarificationQuestion as C, type DatabaseTypes$1 as D, type UseDbInsertResult as E, type Filter as F, type UseDbUpdateOptions as G, type UseDbUpdateResult as H, type UseDbUpsertOptions as I, type UseDbUpsertResult as J, type UseDbDeleteOptions as K, type UseDbDeleteResult as L, useDataLayerCoreOptional as M, type PublicTableNames$1 as P, type QueryState as Q, type ResolveRowType$1 as R, type SchemaNames$1 as S, type TableIdentifier$1 as T, type UseAdvanceQueryOptions as U, useDataLayer as a, useDataLayerCore as b, useDataLayerOptional as c, useDataLayerStatus as d, useDbCount as e, useDbDelete as f, useDbInfiniteQuery as g, useDbInsert as h, useDbQuery as i, useDbQueryById as j, useDbUpdate as k, useDbUpsert as l, type SchemaTableNames$1 as m, type UseAdvanceQueryResult as n, type UseDbCountOptions as o, type UseDbCountResult as p, type UseDbInfiniteQueryOptions as q, type UseDbInfiniteQueryResult as r, type UseDbQueryOptions as s, type UseDbQueryResult as t, useAdvanceQuery as u, type UseDbQueryByIdOptions as v, type UseDbQueryByIdResult as w, type FilterGroup as x, type FilterOperator as y, type Pagination as z };
@@ -1,22 +1,23 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
2
  import { UseMutationResult, UseMutationOptions, UseQueryOptions } from '@tanstack/react-query';
3
3
  import { SupabaseClient, PostgrestSingleResponse as PostgrestSingleResponse$1, PostgrestError } from '@supabase/supabase-js';
4
- import { T as TableDataAdapter, C as CapableDataAdapter, c as AdapterCapabilities, A as AdapterQueryResult } from './DataLayerContext-Dc7nF2IG.js';
4
+ import { T as TableDataAdapter, C as CapableDataAdapter, c as AdapterCapabilities, A as AdapterQueryResult } from './DataLayerContext-BwMk4VpG.js';
5
5
  import { DatabaseSchema, QueryOptions } from './core/index.js';
6
6
  import { FunctionsResponse } from '@supabase/functions-js';
7
7
  import * as _supabase_postgrest_js from '@supabase/postgrest-js';
8
8
  import { PostgrestSingleResponse } from '@supabase/postgrest-js';
9
9
  import { G as GetResult } from './select-query-parser-BwyHum1L.js';
10
10
  import { G as GenericTable } from './types-CYr9JiUE.js';
11
- import { D as Database } from './useSupabase-DvWVuHHE.js';
12
- import { D as DbChangeLog, Q as QueryState } from './index-CYFdO0iB.js';
11
+ import { D as Database } from './useSupabase-DSZNeXnF.js';
12
+ import { D as DbChangeLog, Q as QueryState } from './index-lveh8qb0.js';
13
13
  import { U as UseDbQuerySingleReturn } from './useDbQuery-C-TL8jY1.js';
14
- import { J as UseDbUpsertResult } from './useDbCount-Dk0yCKlT.js';
14
+ import { J as UseDbUpsertResult } from './useDbCount-DWfYB2iu.js';
15
15
  import { Moment } from 'moment';
16
16
  import * as react from 'react';
17
17
  import { ReactNode } from 'react';
18
- import { TransformOptions } from '@supabase/storage-js';
19
18
  import * as react_jsx_runtime from 'react/jsx-runtime';
19
+ import { TransformOptions } from '@supabase/storage-js';
20
+ import { ItemType } from '@pol-studios/utils';
20
21
 
21
22
  declare function setSupabaseUrl(url: string): void;
22
23
  declare function getSupabaseUrl(): string;
@@ -81,6 +82,11 @@ declare class SupabaseAdapter implements TableDataAdapter, CapableDataAdapter {
81
82
  * @returns Object with schema (defaults to "public") and tableName
82
83
  */
83
84
  private parseTableIdentifier;
85
+ /**
86
+ * Check if a where clause contains invalid UUID values (empty strings for id fields).
87
+ * Returns true if any id field has an empty string value.
88
+ */
89
+ private hasInvalidUuidFilter;
84
90
  /**
85
91
  * Execute a query and return results with optional count
86
92
  *
@@ -118,6 +124,10 @@ declare class SupabaseAdapter implements TableDataAdapter, CapableDataAdapter {
118
124
  /**
119
125
  * Upsert (insert or update) a record
120
126
  *
127
+ * When the data has an ID, tries UPDATE first to support partial updates
128
+ * (which may not include all NOT NULL columns). Falls back to INSERT
129
+ * if no rows were updated.
130
+ *
121
131
  * @param table - The table name
122
132
  * @param data - The data to upsert
123
133
  * @returns Promise resolving to the upserted record
@@ -280,9 +290,69 @@ declare function useAutosaveState<T extends TItem & {
280
290
  UseDbUpsertResult<T>,
281
291
  React.Dispatch<React.SetStateAction<T>>,
282
292
  (newEntity: T) => void,
283
- () => Promise<void>
293
+ () => Promise<void>,
294
+ T,
295
+ (newBase: T) => void
284
296
  ];
285
297
 
298
+ /**
299
+ * useAutosave Hook v2.0
300
+ *
301
+ * A simple, robust autosave hook for PowerSync offline-first apps.
302
+ *
303
+ * Key design principles:
304
+ * 1. PowerSync SQLite is the single source of truth
305
+ * 2. Dirty buffer (ref) accumulates field-level patches - no complex state
306
+ * 3. Reconciliation: when watched value matches dirty value, clear entry
307
+ * 4. Entity switching: flush old entity immediately, new entity starts fresh
308
+ * 5. No baseValue tracking - watchedData IS the base
309
+ *
310
+ * @example
311
+ * ```tsx
312
+ * const { data } = useDbQuery("Task", { where: { id: taskId }, realtime: true });
313
+ *
314
+ * const { value, patch, isSaving } = useAutosave(
315
+ * "Task",
316
+ * taskId,
317
+ * data?.[0] ?? null,
318
+ * { delay: 2000 }
319
+ * );
320
+ *
321
+ * <TextInput value={value?.title} onChangeText={t => patch({ title: t })} />
322
+ * ```
323
+ */
324
+ interface UseAutosaveOptions {
325
+ /** Debounce delay in ms before saving (default: 2000) */
326
+ delay?: number;
327
+ }
328
+ interface UseAutosaveResult<T> {
329
+ /** The merged value: dirty fields overlaid on watchedData */
330
+ value: T | null;
331
+ /** Update one or more fields. Starts the debounce timer. */
332
+ patch: (updates: Partial<T>) => void;
333
+ /** Force-flush any pending changes immediately */
334
+ flush: () => Promise<void>;
335
+ /** Re-trigger save after error, no user edit required */
336
+ retry: () => void;
337
+ /** True while save is in-flight for current entity */
338
+ isSaving: boolean;
339
+ /** Last error from save attempt */
340
+ saveError: Error | null;
341
+ /** Clear the error without triggering save */
342
+ clearError: () => void;
343
+ }
344
+ /**
345
+ * Autosave hook that manages optimistic local edits with debounced persistence.
346
+ *
347
+ * @param table - The table name to save to
348
+ * @param entityId - The entity ID (null = hook is inert)
349
+ * @param watchedData - Live data from useDbQuery with realtime:true
350
+ * @param options - Configuration options
351
+ */
352
+ declare function useAutosave<T extends {
353
+ id: string;
354
+ }>(table: string, entityId: string | null, watchedData: T | null, options?: UseAutosaveOptions): UseAutosaveResult<T>;
355
+
286
356
  declare function useToastError<T>(mutation: UseDbUpsertResult<T>): UseDbUpsertResult<T>;
287
357
 
288
358
  declare function executeAdvanceQuery<Result>(supabase: any, query: PromiseLike<PostgrestSingleResponse$1<Result>>, filterLayer: QueryState): Promise<{
@@ -542,103 +612,89 @@ declare function useDbPartialQuery<Result extends Record<string, any>[]>(query:
542
612
 
543
613
  type CustomPageQueryResult<T extends Record<string, any>[]> = ReturnType<typeof useDbPartialQuery<T>>;
544
614
 
545
- type Attachment = {
546
- bucketId: string;
547
- path: string;
548
- };
549
- declare function useStorageUrl(): {
550
- fetchUrl: (entity: {
551
- bucketId: string;
552
- path: string;
553
- }, options?: {
554
- download?: string | boolean;
555
- transform?: TransformOptions;
556
- }) => Promise<string>;
557
- fetchUrls: (entities: Attachment[], options?: {
558
- download?: string | boolean;
559
- transform?: TransformOptions;
560
- }) => Promise<Map<string, string | undefined>>;
561
- prefetchImage: (entity: Attachment, options?: {
562
- download?: string | boolean;
563
- transform?: TransformOptions;
564
- }) => Promise<void>;
565
- fetchPublicUrl: (entity: {
566
- bucketId: string;
567
- path: string;
568
- }, options?: {
569
- download?: string | boolean;
570
- transform?: TransformOptions;
571
- }) => Promise<string>;
572
- expireCache: (entity: {
573
- bucketId: string;
574
- path: string;
575
- }) => Promise<void>;
576
- getCacheVersion: (entity: {
577
- bucketId: string;
578
- path: string;
579
- }) => number;
580
- subscribeToCacheVersion: (entity: {
581
- bucketId: string;
582
- path: string;
583
- }, callback: () => void) => () => void;
584
- };
585
-
586
615
  /**
587
- * Metadata stored in storage.objects.metadata JSONB column
616
+ * Async attachment queue provider for PowerSync integration.
617
+ * Used for async-first local lookups.
588
618
  */
589
- interface StorageObjectMetadata {
590
- processingStatus: "None" | "Processing" | "Error";
591
- contentType: string;
592
- contentHeight?: number;
593
- contentWidth?: number;
594
- originalFileName?: string;
595
- legacyAttachmentId?: number;
619
+ interface AttachmentQueueProvider {
620
+ /** Get local file URI for a storage path asynchronously, or null if not cached */
621
+ getLocalUriForStoragePath: (storagePath: string) => Promise<string | null>;
622
+ /**
623
+ * Subscribe to cache/download progress updates. Returns cleanup function.
624
+ *
625
+ * Note: Callback uses `...args: unknown[]` for structural compatibility with
626
+ * PolAttachmentQueue.onProgress which passes stats. This package doesn't need
627
+ * the stats, so we accept any args to avoid importing PowerSync types.
628
+ */
629
+ onProgress?: (callback: (...args: unknown[]) => void) => () => void;
596
630
  }
597
- type UseStoragePathOptions = {
598
- /** Whether to fetch metadata from storage.objects (default: true) */
599
- fetchMetadata?: boolean;
600
- /** Transform options for the URL */
601
- transform?: {
602
- width?: number;
603
- height?: number;
604
- quality?: number;
605
- format?: "origin";
606
- };
607
- /** Whether to get a download URL */
608
- download?: string | boolean;
609
- };
610
- type UseStoragePathResult = {
611
- /** Signed URL for the storage object */
612
- url: string | null;
613
- /** Metadata from storage.objects.metadata JSONB */
614
- metadata: StorageObjectMetadata | null;
615
- /** Content type (from metadata or inferred from path) */
616
- contentType: string;
617
- /** Whether the URL or metadata is still loading */
631
+ interface UseStorageSourceOptions {
632
+ /** Storage bucket ID (defaults to UNIT_DOCUMENTATION) */
633
+ bucketId?: string;
634
+ /** Whether to enable the hook (defaults to true) */
635
+ enabled?: boolean;
636
+ /** Image transform options for Supabase */
637
+ transform?: TransformOptions;
638
+ /**
639
+ * PowerSync attachment queue for async local-first caching.
640
+ */
641
+ attachmentQueue?: AttachmentQueueProvider | null;
642
+ /** Use public URL instead of signed URL (defaults to false) */
643
+ usePublicUrl?: boolean;
644
+ }
645
+ interface UseStorageSourceResult {
646
+ /** Resolved URI (local file:// or remote signed URL) */
647
+ uri: string | null;
648
+ /** Whether the URI is currently being fetched */
618
649
  isLoading: boolean;
619
- /** Error if URL fetch failed */
650
+ /** Whether the URI is from local cache */
651
+ isLocal: boolean;
652
+ /** Error if fetching failed */
620
653
  error: Error | null;
621
- };
654
+ /** Force refresh the URI */
655
+ refresh: () => void;
656
+ /** Imperatively fetch a signed URL for any path (checks local cache first) */
657
+ getSignedUrl: (path: string, options?: {
658
+ transform?: TransformOptions;
659
+ }) => Promise<string | null>;
660
+ /** Clear local state and trigger a refresh */
661
+ invalidate: () => void;
662
+ }
622
663
  /**
623
- * Hook to get a signed URL and metadata for a storage path.
624
- * Replaces useAttachment for the path-based storage approach.
664
+ * Standalone utility for fetching storage URLs outside React components.
665
+ * Does not check local cache - use for server-side or non-React contexts.
666
+ * Includes session refresh retry logic for auth errors.
667
+ */
668
+ declare function getStorageUrl(supabase: SupabaseClient, storagePath: string, options?: {
669
+ bucketId?: string;
670
+ transform?: TransformOptions;
671
+ usePublicUrl?: boolean;
672
+ }): Promise<string | null>;
673
+ /**
674
+ * Unified hook for resolving storage URLs with optional local-first caching.
625
675
  *
626
- * @param storagePath - The path within the bucket (e.g., "14/abc-123.jpg")
627
- * @param bucketId - The storage bucket ID
628
- * @param options - Optional configuration
676
+ * Works on both web and React Native:
677
+ * - On web (no attachmentQueue): Fetches Supabase signed URLs directly
678
+ * - On RN with PowerSync: Checks local attachment cache first, falls back to signed URLs
629
679
  *
630
680
  * @example
631
- * ```tsx
632
- * const { url, contentType, isLoading } = useStoragePath(
633
- * profile.profilePath,
634
- * 'attachments'
635
- * );
681
+ * // Basic usage (web or RN without local cache)
682
+ * const { uri, isLoading } = useStorageSource(photo.storage_path);
636
683
  *
637
- * if (isLoading) return <Spinner />;
638
- * return <img src={url} />;
639
- * ```
684
+ * @example
685
+ * // With PowerSync attachment queue (RN)
686
+ * const attachmentQueue = useAttachmentQueue();
687
+ * const { uri, isLocal } = useStorageSource(photo.storage_path, {
688
+ * attachmentQueue,
689
+ * });
690
+ *
691
+ * @example
692
+ * // With transform options
693
+ * const { uri } = useStorageSource(photo.storage_path, {
694
+ * transform: { width: 200, height: 200, resize: 'contain' },
695
+ * });
640
696
  */
641
- declare function useStoragePath(storagePath: string | undefined | null, bucketId: string, options?: UseStoragePathOptions): UseStoragePathResult;
697
+ declare function useStorageSource(storagePath: string | null | undefined, options?: UseStorageSourceOptions): UseStorageSourceResult;
642
698
 
643
699
  /**
644
700
  * Storage bucket names for Supabase storage.
@@ -661,12 +717,60 @@ declare const BUCKETS: {
661
717
  };
662
718
  type BucketName = (typeof BUCKETS)[keyof typeof BUCKETS];
663
719
 
720
+ interface StorageQueueProviderProps {
721
+ children: ReactNode;
722
+ /** The attachment queue instance (from @pol/powersync or any conforming implementation) */
723
+ attachmentQueue: AttachmentQueueProvider | null;
724
+ /** Whether the queue has finished its async init */
725
+ isReady: boolean;
726
+ }
727
+ declare function StorageQueueProvider({ children, attachmentQueue, isReady, }: StorageQueueProviderProps): react_jsx_runtime.JSX.Element;
728
+
729
+ interface StorageQueueContextValue {
730
+ /** The attachment queue provider, or null if not available */
731
+ attachmentQueue: AttachmentQueueProvider | null;
732
+ /** Whether the queue has finished initializing (cold start guard) */
733
+ isReady: boolean;
734
+ }
735
+ declare const StorageQueueContext: react.Context<StorageQueueContextValue>;
736
+ /**
737
+ * Internal hook used by useStorageSource to auto-detect the queue.
738
+ * Returns null if no StorageQueueProvider is present (web, tests, etc.)
739
+ */
740
+ declare function useStorageQueueContext(): StorageQueueContextValue | null;
741
+
664
742
  declare function createInCondition(column: string, values: (string | number)[]): string;
665
743
 
666
744
  declare const TIMEOUT_ERROR_MESSAGE = "Request timed out";
667
745
  declare const DEFAULT_QUERY_TIMEOUT = 15000;
668
746
  declare function isTimeoutError(error: Error | null | undefined): boolean;
669
747
 
748
+ type ConfigurationOptions<T> = {
749
+ crossOrganization?: boolean;
750
+ };
751
+ type FilterOperator = "or" | "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "like" | "ilike" | "is" | "in" | "cs" | "cd" | "fts" | "plfts";
752
+ type ValueType = number | string | boolean | null | Date | object;
753
+ type FilterDefinition = {
754
+ path: string;
755
+ alias?: string;
756
+ operator: FilterOperator;
757
+ negate: boolean;
758
+ value: ValueType;
759
+ };
760
+ type FilterDefinitions = (FilterComposite | FilterDefinition)[];
761
+ type FilterComposite = {
762
+ or?: FilterDefinitions;
763
+ and?: FilterDefinitions;
764
+ };
765
+ type UseDbRealtimeQueryResult<T> = UseDbQuerySingleReturn<T> & {
766
+ realtimeStatus: "SUBSCRIBED" | "TIMED_OUT" | "CLOSED" | "CHANNEL_ERROR" | "Loading...";
767
+ isRealtimeConnected: boolean;
768
+ isRealtimeLoading: boolean;
769
+ };
770
+ type DataType = Record<string, any>;
771
+ declare function convertFilterToRealtimeQuery(filters: FilterDefinitions): string;
772
+ declare function useDbRealtimeQuery<Result extends DataType>(query: PromiseLike<PostgrestSingleResponse$1<Result>>, config?: Omit<UseQueryOptions<PostgrestSingleResponse$1<Result>>, "queryKey" | "queryFn"> & ConfigurationOptions<Result>, primaryKeys?: (keyof ItemType<Result> & string)[]): UseDbRealtimeQueryResult<Result>;
773
+
670
774
  interface AlertProps {
671
775
  title: string;
672
776
  description: string;
@@ -879,4 +983,4 @@ declare function useResolveFeedback(): _tanstack_react_query.UseMutationResult<{
879
983
  }>;
880
984
  }, Error, number, unknown>;
881
985
 
882
- export { type SubmitFeedbackParams as $, type AIOptions as A, BUCKETS as B, type CustomPageQueryResult as C, DEFAULT_QUERY_TIMEOUT as D, useUpsertChangelog as E, useDeleteChangelog as F, useUpsertChangelogEntry as G, useMultiUpsertChangelogEntries as H, useDeleteChangelogEntry as I, useMultiDeleteChangelogEntries as J, useUpsertChangelogMedia as K, LiveChangeContext as L, useDeleteChangelogMedia as M, useUploadChangelogMedia as N, useChangelogs as O, usePublishedChangelogs as P, useChangelogById as Q, useChangelogBySlug as R, SupabaseAdapter as S, TIMEOUT_ERROR_MESSAGE as T, type UseMutationSuccessOptions as U, useChangelogEntries as V, useChangelogMedia as W, useFeedbackList as X, type FeedbackListItem as Y, type FeedbackListParams as Z, useSubmitFeedback as _, useLatestOperationLog as a, useApplyFeedback as a0, useResolveFeedback as a1, type UseDbPartialQueryResult as a2, useDbPartialQuery as a3, useAutosaveState as b, useToastError as c, useStorageUrl as d, useStoragePath as e, useMutationSuccess as f, getSupabaseUrl as g, useMutationSuccessRN as h, createSupabaseAdapter as i, getErrorBody as j, type AIResponse as k, useAI as l, type ServerAvailabilityState as m, newTimeActivity as n, useServerAvailability as o, useSearchQuery as p, type UpdateOptions as q, executeAdvanceQuery as r, setSupabaseUrl as s, type StorageObjectMetadata as t, useLiveChangeTracking as u, type BucketName as v, createInCondition as w, isTimeoutError as x, type AlertProps as y, LiveChangeContextProvider as z };
986
+ export { useUpsertChangelogMedia as $, type AttachmentQueueProvider as A, useAI as B, type ServerAvailabilityState as C, useServerAvailability as D, useSearchQuery as E, type UpdateOptions as F, executeAdvanceQuery as G, type CustomPageQueryResult as H, BUCKETS as I, type BucketName as J, createInCondition as K, DEFAULT_QUERY_TIMEOUT as L, isTimeoutError as M, type UseDbRealtimeQueryResult as N, convertFilterToRealtimeQuery as O, type AlertProps as P, LiveChangeContext as Q, LiveChangeContextProvider as R, StorageQueueProvider as S, TIMEOUT_ERROR_MESSAGE as T, type UseAutosaveOptions as U, useUpsertChangelog as V, useDeleteChangelog as W, useUpsertChangelogEntry as X, useMultiUpsertChangelogEntries as Y, useDeleteChangelogEntry as Z, useMultiDeleteChangelogEntries as _, useLatestOperationLog as a, useDeleteChangelogMedia as a0, useUploadChangelogMedia as a1, useChangelogs as a2, usePublishedChangelogs as a3, useChangelogById as a4, useChangelogBySlug as a5, useChangelogEntries as a6, useChangelogMedia as a7, useFeedbackList as a8, type FeedbackListItem as a9, type FeedbackListParams as aa, useSubmitFeedback as ab, type SubmitFeedbackParams as ac, useApplyFeedback as ad, useResolveFeedback as ae, type UseDbPartialQueryResult as af, useDbPartialQuery as ag, useAutosaveState as b, useAutosave as c, type UseAutosaveResult as d, useToastError as e, useStorageSource as f, getStorageUrl as g, type UseStorageSourceOptions as h, type UseStorageSourceResult as i, type StorageQueueProviderProps as j, StorageQueueContext as k, useStorageQueueContext as l, type StorageQueueContextValue as m, newTimeActivity as n, useDbRealtimeQuery as o, getSupabaseUrl as p, type UseMutationSuccessOptions as q, useMutationSuccess as r, setSupabaseUrl as s, useMutationSuccessRN as t, useLiveChangeTracking as u, SupabaseAdapter as v, createSupabaseAdapter as w, getErrorBody as x, type AIOptions as y, type AIResponse as z };
@@ -21,7 +21,7 @@ declare function useSupabase(): SupabaseClient<any, "public", "public", any, any
21
21
  declare function SupabaseProvider({ children, options, afterInitialize, supabaseClient: supabaseClientProp, }: {
22
22
  children: ReactNode;
23
23
  options?: SupabaseClientOptions<string & keyof Database>;
24
- afterInitialize?: (supabase: SupabaseClient<Database>) => any;
24
+ afterInitialize?: (supabase: SupabaseClient<Database>) => void | (() => void);
25
25
  supabaseClient?: SupabaseClient<Database>;
26
26
  }): react_jsx_runtime.JSX.Element;
27
27
 
@@ -1,8 +1,8 @@
1
- import { u as useSupabase } from '../useSupabase-DvWVuHHE.js';
1
+ import { u as useSupabase } from '../useSupabase-DSZNeXnF.js';
2
2
  import { a as ProfileStatus } from '../setupAuthContext-B76nbIP6.js';
3
3
  import * as _tanstack_react_query from '@tanstack/react-query';
4
4
  import { useMutation, useQuery } from '@tanstack/react-query';
5
- export { e as UserMetadataContextProvider, c as UserMetadataContextType, a as UserMetadataInsert, U as UserMetadataRow, b as UserMetadataUpdate, u as useLiveChangesIndicator, h as useSetUserMetadata, i as useUserMetadataState, g as useUserMetadataValue, d as userMetadataContext } from '../UserMetadataContext-B8gVWGMl.js';
5
+ export { e as UserMetadataContextProvider, c as UserMetadataContextType, a as UserMetadataInsert, U as UserMetadataRow, b as UserMetadataUpdate, u as useLiveChangesIndicator, h as useSetUserMetadata, i as useUserMetadataState, g as useUserMetadataValue, d as userMetadataContext } from '../UserMetadataContext-pQb3A8_Q.js';
6
6
  import { UseQuerySingleReturn } from '@supabase-cache-helpers/postgrest-react-query';
7
7
  import { T as Tables } from '../database.types-ChFCG-4M.js';
8
8
  import 'react/jsx-runtime';
@@ -5,38 +5,36 @@ import {
5
5
  useUserMetadataState,
6
6
  useUserMetadataValue,
7
7
  userMetadataContext
8
- } from "../chunk-ADD5MIMK.js";
8
+ } from "../chunk-FESQS4S5.js";
9
+ import {
10
+ useDbUpsert
11
+ } from "../chunk-NP34C3O3.js";
9
12
  import "../chunk-SM73S2DY.js";
10
- import "../chunk-NSIAAYW3.js";
13
+ import "../chunk-6KN7KLEG.js";
14
+ import "../chunk-5HJLTYRA.js";
11
15
  import {
12
16
  useAuth,
13
17
  useSetupAuth
14
- } from "../chunk-5BLKZUKM.js";
18
+ } from "../chunk-MREERKQU.js";
15
19
  import {
16
20
  useDbQuery
17
- } from "../chunk-WX4ABYIF.js";
18
- import {
19
- useDbUpsert
20
- } from "../chunk-VGEMLNNM.js";
21
- import "../chunk-HAWJTZCK.js";
21
+ } from "../chunk-67HMVGV7.js";
22
+ import "../chunk-UBHORKBS.js";
23
+ import "../chunk-RT4O5H2E.js";
22
24
  import {
23
25
  getSupabaseUrl
24
26
  } from "../chunk-GC3TBUWE.js";
25
27
  import "../chunk-J4ZVCXZ4.js";
26
- import {
27
- isNullOrWhitespace,
28
- isUsable,
29
- newUuid
30
- } from "../chunk-OQ7U6EQ3.js";
31
- import "../chunk-H6365JPC.js";
32
- import "../chunk-3PJTNH2L.js";
28
+ import "../chunk-YUX6RGLZ.js";
29
+ import "../chunk-AKIRHA4Q.js";
33
30
  import {
34
31
  useSupabase
35
- } from "../chunk-5EFDS7SR.js";
36
- import "../chunk-P4UZ7IXC.js";
32
+ } from "../chunk-DMVUEJG2.js";
33
+ import "../chunk-7D4SUZUM.js";
37
34
 
38
35
  // src/hooks/useConsent.ts
39
36
  import { useCallback, useMemo } from "react";
37
+ import { isUsable } from "@pol-studios/utils";
40
38
  function useConsent() {
41
39
  const supabase = useSupabase();
42
40
  const {
@@ -888,6 +886,7 @@ var useDataExport_default = useDataExport;
888
886
 
889
887
  // src/useBackgroundTask.tsx
890
888
  import { c as _c4 } from "react/compiler-runtime";
889
+ import { isUsable as isUsable2 } from "@pol-studios/utils";
891
890
  import { useToast } from "@pol-studios/hooks/toast";
892
891
  function useBackgroundTask() {
893
892
  const $ = _c4(12);
@@ -904,16 +903,28 @@ function useBackgroundTask() {
904
903
  if (user == null) {
905
904
  return;
906
905
  }
907
- const taskResponse = await supabase.schema("core").from("Task").insert({
908
- payload: request.body,
909
- handlerId: request.handlerId,
910
- title: request.title,
911
- description: request.description,
912
- createdBy: user.id,
913
- payloadLength: JSON.stringify(request.body).length
914
- }).select();
915
- const task = taskResponse.data?.[0];
916
- if (isUsable(task) === false) {
906
+ const response = await supabase.functions.invoke("background-task-orchestrator", {
907
+ body: {
908
+ taskId: request.handlerId,
909
+ title: request.title,
910
+ description: request.description,
911
+ payload: request.body
912
+ }
913
+ });
914
+ if (response.error) {
915
+ if (response.error.message?.includes("rate limit") || response.error.message?.includes("429")) {
916
+ toast({
917
+ title: "Too many requests. Please try again later."
918
+ });
919
+ } else {
920
+ toast({
921
+ title: "Failed to start task"
922
+ });
923
+ }
924
+ throw response.error;
925
+ }
926
+ const task = response.data?.task;
927
+ if (isUsable2(task) === false) {
917
928
  return;
918
929
  }
919
930
  toast({
@@ -931,17 +942,17 @@ function useBackgroundTask() {
931
942
  let t1;
932
943
  if ($[4] !== supabase) {
933
944
  t1 = async function retryTask2(taskId) {
934
- const response = await supabase.functions.invoke("trigger-update", {
945
+ const response_0 = await supabase.functions.invoke("trigger-update", {
935
946
  body: {
936
947
  taskId,
937
948
  action: "retry"
938
949
  }
939
950
  });
940
- console.log(response.data);
941
- if (response.error) {
942
- throw response.error;
951
+ console.log(response_0.data);
952
+ if (response_0.error) {
953
+ throw response_0.error;
943
954
  }
944
- return response.data.id;
955
+ return response_0.data.id;
945
956
  };
946
957
  $[4] = supabase;
947
958
  $[5] = t1;
@@ -984,6 +995,7 @@ function useBackgroundTask() {
984
995
 
985
996
  // src/useUserMetadata.tsx
986
997
  import { c as _c5 } from "react/compiler-runtime";
998
+ import { isUsable as isUsable3 } from "@pol-studios/utils";
987
999
  function useUserMetadata(key) {
988
1000
  const $ = _c5(16);
989
1001
  const supabase = useSupabase();
@@ -1012,7 +1024,7 @@ function useUserMetadata(key) {
1012
1024
  }
1013
1025
  let t2;
1014
1026
  if ($[5] !== user) {
1015
- t2 = isUsable(user);
1027
+ t2 = isUsable3(user);
1016
1028
  $[5] = user;
1017
1029
  $[6] = t2;
1018
1030
  } else {
@@ -1064,6 +1076,7 @@ function useUserMetadata(key) {
1064
1076
  import { c as _c6 } from "react/compiler-runtime";
1065
1077
  import { useMutation as useMutation4 } from "@tanstack/react-query";
1066
1078
  import { Upload } from "tus-js-client";
1079
+ import { isNullOrWhitespace, newUuid } from "@pol-studios/utils";
1067
1080
  async function uploadFileWithMetadata(supabase, bucketName, filePath, file, metadata, onProgress) {
1068
1081
  const {
1069
1082
  data: {