@tanstack/offline-transactions 1.0.1 → 1.0.3

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 (55) hide show
  1. package/README.md +14 -14
  2. package/dist/cjs/OfflineExecutor.cjs.map +1 -1
  3. package/dist/cjs/api/OfflineAction.cjs.map +1 -1
  4. package/dist/cjs/api/OfflineTransaction.cjs.map +1 -1
  5. package/dist/cjs/connectivity/OnlineDetector.cjs.map +1 -1
  6. package/dist/cjs/coordination/BroadcastChannelLeader.cjs.map +1 -1
  7. package/dist/cjs/coordination/LeaderElection.cjs.map +1 -1
  8. package/dist/cjs/coordination/WebLocksLeader.cjs.map +1 -1
  9. package/dist/cjs/executor/KeyScheduler.cjs.map +1 -1
  10. package/dist/cjs/executor/TransactionExecutor.cjs.map +1 -1
  11. package/dist/cjs/outbox/OutboxManager.cjs.map +1 -1
  12. package/dist/cjs/outbox/TransactionSerializer.cjs.map +1 -1
  13. package/dist/cjs/retry/RetryPolicy.cjs.map +1 -1
  14. package/dist/cjs/storage/IndexedDBAdapter.cjs.map +1 -1
  15. package/dist/cjs/storage/LocalStorageAdapter.cjs.map +1 -1
  16. package/dist/cjs/storage/StorageAdapter.cjs.map +1 -1
  17. package/dist/cjs/telemetry/tracer.cjs.map +1 -1
  18. package/dist/cjs/types.cjs.map +1 -1
  19. package/dist/esm/OfflineExecutor.js.map +1 -1
  20. package/dist/esm/api/OfflineAction.js.map +1 -1
  21. package/dist/esm/api/OfflineTransaction.js.map +1 -1
  22. package/dist/esm/connectivity/OnlineDetector.js.map +1 -1
  23. package/dist/esm/coordination/BroadcastChannelLeader.js.map +1 -1
  24. package/dist/esm/coordination/LeaderElection.js.map +1 -1
  25. package/dist/esm/coordination/WebLocksLeader.js.map +1 -1
  26. package/dist/esm/executor/KeyScheduler.js.map +1 -1
  27. package/dist/esm/executor/TransactionExecutor.js.map +1 -1
  28. package/dist/esm/outbox/OutboxManager.js.map +1 -1
  29. package/dist/esm/outbox/TransactionSerializer.js.map +1 -1
  30. package/dist/esm/retry/RetryPolicy.js.map +1 -1
  31. package/dist/esm/storage/IndexedDBAdapter.js.map +1 -1
  32. package/dist/esm/storage/LocalStorageAdapter.js.map +1 -1
  33. package/dist/esm/storage/StorageAdapter.js.map +1 -1
  34. package/dist/esm/telemetry/tracer.js.map +1 -1
  35. package/dist/esm/types.js.map +1 -1
  36. package/package.json +10 -13
  37. package/src/OfflineExecutor.ts +26 -26
  38. package/src/api/OfflineAction.ts +6 -6
  39. package/src/api/OfflineTransaction.ts +6 -6
  40. package/src/connectivity/OnlineDetector.ts +2 -2
  41. package/src/coordination/BroadcastChannelLeader.ts +1 -1
  42. package/src/coordination/LeaderElection.ts +1 -1
  43. package/src/coordination/WebLocksLeader.ts +3 -3
  44. package/src/executor/KeyScheduler.ts +12 -12
  45. package/src/executor/TransactionExecutor.ts +22 -22
  46. package/src/index.ts +16 -16
  47. package/src/outbox/OutboxManager.ts +17 -17
  48. package/src/outbox/TransactionSerializer.ts +7 -7
  49. package/src/retry/NonRetriableError.ts +1 -1
  50. package/src/retry/RetryPolicy.ts +3 -3
  51. package/src/storage/IndexedDBAdapter.ts +3 -3
  52. package/src/storage/LocalStorageAdapter.ts +3 -3
  53. package/src/storage/StorageAdapter.ts +1 -1
  54. package/src/telemetry/tracer.ts +3 -3
  55. package/src/types.ts +3 -3
@@ -1,7 +1,7 @@
1
- import { withSpan } from "../telemetry/tracer"
2
- import { TransactionSerializer } from "./TransactionSerializer"
3
- import type { OfflineTransaction, StorageAdapter } from "../types"
4
- import type { Collection } from "@tanstack/db"
1
+ import { withSpan } from '../telemetry/tracer'
2
+ import { TransactionSerializer } from './TransactionSerializer'
3
+ import type { OfflineTransaction, StorageAdapter } from '../types'
4
+ import type { Collection } from '@tanstack/db'
5
5
 
6
6
  export class OutboxManager {
7
7
  private storage: StorageAdapter
@@ -11,7 +11,7 @@ export class OutboxManager {
11
11
  constructor(
12
12
  storage: StorageAdapter,
13
13
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
- collections: Record<string, Collection<any, any, any, any, any>>
14
+ collections: Record<string, Collection<any, any, any, any, any>>,
15
15
  ) {
16
16
  this.storage = storage
17
17
  this.serializer = new TransactionSerializer(collections)
@@ -25,20 +25,20 @@ export class OutboxManager {
25
25
  return withSpan(
26
26
  `outbox.add`,
27
27
  {
28
- "transaction.id": transaction.id,
29
- "transaction.mutationFnName": transaction.mutationFnName,
30
- "transaction.keyCount": transaction.keys.length,
28
+ 'transaction.id': transaction.id,
29
+ 'transaction.mutationFnName': transaction.mutationFnName,
30
+ 'transaction.keyCount': transaction.keys.length,
31
31
  },
32
32
  async () => {
33
33
  const key = this.getStorageKey(transaction.id)
34
34
  const serialized = this.serializer.serialize(transaction)
35
35
  await this.storage.set(key, serialized)
36
- }
36
+ },
37
37
  )
38
38
  }
39
39
 
40
40
  async get(id: string): Promise<OfflineTransaction | null> {
41
- return withSpan(`outbox.get`, { "transaction.id": id }, async (span) => {
41
+ return withSpan(`outbox.get`, { 'transaction.id': id }, async (span) => {
42
42
  const key = this.getStorageKey(id)
43
43
  const data = await this.storage.get(key)
44
44
 
@@ -63,7 +63,7 @@ export class OutboxManager {
63
63
  return withSpan(`outbox.getAll`, {}, async (span) => {
64
64
  const keys = await this.storage.keys()
65
65
  const transactionKeys = keys.filter((key) =>
66
- key.startsWith(this.keyPrefix)
66
+ key.startsWith(this.keyPrefix),
67
67
  )
68
68
 
69
69
  span.setAttribute(`transactionCount`, transactionKeys.length)
@@ -79,14 +79,14 @@ export class OutboxManager {
79
79
  } catch (error) {
80
80
  console.warn(
81
81
  `Failed to deserialize transaction from key ${key}:`,
82
- error
82
+ error,
83
83
  )
84
84
  }
85
85
  }
86
86
  }
87
87
 
88
88
  return transactions.sort(
89
- (a, b) => a.createdAt.getTime() - b.createdAt.getTime()
89
+ (a, b) => a.createdAt.getTime() - b.createdAt.getTime(),
90
90
  )
91
91
  })
92
92
  }
@@ -96,15 +96,15 @@ export class OutboxManager {
96
96
  const keySet = new Set(keys)
97
97
 
98
98
  return allTransactions.filter((transaction) =>
99
- transaction.keys.some((key) => keySet.has(key))
99
+ transaction.keys.some((key) => keySet.has(key)),
100
100
  )
101
101
  }
102
102
 
103
103
  async update(
104
104
  id: string,
105
- updates: Partial<OfflineTransaction>
105
+ updates: Partial<OfflineTransaction>,
106
106
  ): Promise<void> {
107
- return withSpan(`outbox.update`, { "transaction.id": id }, async () => {
107
+ return withSpan(`outbox.update`, { 'transaction.id': id }, async () => {
108
108
  const existing = await this.get(id)
109
109
  if (!existing) {
110
110
  throw new Error(`Transaction ${id} not found`)
@@ -116,7 +116,7 @@ export class OutboxManager {
116
116
  }
117
117
 
118
118
  async remove(id: string): Promise<void> {
119
- return withSpan(`outbox.remove`, { "transaction.id": id }, async () => {
119
+ return withSpan(`outbox.remove`, { 'transaction.id': id }, async () => {
120
120
  const key = this.getStorageKey(id)
121
121
  await this.storage.delete(key)
122
122
  })
@@ -3,8 +3,8 @@ import type {
3
3
  SerializedError,
4
4
  SerializedMutation,
5
5
  SerializedOfflineTransaction,
6
- } from "../types"
7
- import type { Collection, PendingMutation } from "@tanstack/db"
6
+ } from '../types'
7
+ import type { Collection, PendingMutation } from '@tanstack/db'
8
8
 
9
9
  export class TransactionSerializer {
10
10
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -13,7 +13,7 @@ export class TransactionSerializer {
13
13
 
14
14
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
15
  constructor(
16
- collections: Record<string, Collection<any, any, any, any, any>>
16
+ collections: Record<string, Collection<any, any, any, any, any>>,
17
17
  ) {
18
18
  this.collections = collections
19
19
  // Create reverse lookup from collection.id to registry key
@@ -28,7 +28,7 @@ export class TransactionSerializer {
28
28
  ...transaction,
29
29
  createdAt: transaction.createdAt,
30
30
  mutations: transaction.mutations.map((mutation) =>
31
- this.serializeMutation(mutation)
31
+ this.serializeMutation(mutation),
32
32
  ),
33
33
  }
34
34
  // Convert the whole object to JSON, handling dates
@@ -52,13 +52,13 @@ export class TransactionSerializer {
52
52
  return new Date(value)
53
53
  }
54
54
  return value
55
- }
55
+ },
56
56
  )
57
57
 
58
58
  return {
59
59
  ...parsed,
60
60
  mutations: parsed.mutations.map((mutationData) =>
61
- this.deserializeMutation(mutationData)
61
+ this.deserializeMutation(mutationData),
62
62
  ),
63
63
  }
64
64
  }
@@ -67,7 +67,7 @@ export class TransactionSerializer {
67
67
  const registryKey = this.collectionIdToKey.get(mutation.collection.id)
68
68
  if (!registryKey) {
69
69
  throw new Error(
70
- `Collection with id ${mutation.collection.id} not found in registry`
70
+ `Collection with id ${mutation.collection.id} not found in registry`,
71
71
  )
72
72
  }
73
73
 
@@ -1 +1 @@
1
- export { NonRetriableError } from "../types"
1
+ export { NonRetriableError } from '../types'
@@ -1,6 +1,6 @@
1
- import { NonRetriableError } from "../types"
2
- import { BackoffCalculator } from "./BackoffCalculator"
3
- import type { RetryPolicy } from "../types"
1
+ import { NonRetriableError } from '../types'
2
+ import { BackoffCalculator } from './BackoffCalculator'
3
+ import type { RetryPolicy } from '../types'
4
4
 
5
5
  export class DefaultRetryPolicy implements RetryPolicy {
6
6
  private backoffCalculator: BackoffCalculator
@@ -1,4 +1,4 @@
1
- import { BaseStorageAdapter } from "./StorageAdapter"
1
+ import { BaseStorageAdapter } from './StorageAdapter'
2
2
 
3
3
  export class IndexedDBAdapter extends BaseStorageAdapter {
4
4
  private dbName: string
@@ -82,7 +82,7 @@ export class IndexedDBAdapter extends BaseStorageAdapter {
82
82
  }
83
83
 
84
84
  private async getStore(
85
- mode: IDBTransactionMode = `readonly`
85
+ mode: IDBTransactionMode = `readonly`,
86
86
  ): Promise<IDBObjectStore> {
87
87
  const db = await this.openDB()
88
88
  const transaction = db.transaction([this.storeName], mode)
@@ -117,7 +117,7 @@ export class IndexedDBAdapter extends BaseStorageAdapter {
117
117
  error.name === `QuotaExceededError`
118
118
  ) {
119
119
  throw new Error(
120
- `Storage quota exceeded. Consider clearing old transactions.`
120
+ `Storage quota exceeded. Consider clearing old transactions.`,
121
121
  )
122
122
  }
123
123
  throw error
@@ -1,4 +1,4 @@
1
- import { BaseStorageAdapter } from "./StorageAdapter"
1
+ import { BaseStorageAdapter } from './StorageAdapter'
2
2
 
3
3
  export class LocalStorageAdapter extends BaseStorageAdapter {
4
4
  private prefix: string
@@ -70,8 +70,8 @@ export class LocalStorageAdapter extends BaseStorageAdapter {
70
70
  ) {
71
71
  return Promise.reject(
72
72
  new Error(
73
- `Storage quota exceeded. Consider clearing old transactions.`
74
- )
73
+ `Storage quota exceeded. Consider clearing old transactions.`,
74
+ ),
75
75
  )
76
76
  }
77
77
  return Promise.reject(error)
@@ -1,4 +1,4 @@
1
- import type { StorageAdapter } from "../types"
1
+ import type { StorageAdapter } from '../types'
2
2
 
3
3
  export abstract class BaseStorageAdapter implements StorageAdapter {
4
4
  abstract get(key: string): Promise<string | null>
@@ -26,7 +26,7 @@ export async function withSpan<T>(
26
26
  name: string,
27
27
  attrs: SpanAttrs,
28
28
  fn: (span: any) => Promise<T>,
29
- _options?: WithSpanOptions
29
+ _options?: WithSpanOptions,
30
30
  ): Promise<T> {
31
31
  return await fn(noopSpan)
32
32
  }
@@ -39,7 +39,7 @@ export async function withNestedSpan<T>(
39
39
  name: string,
40
40
  attrs: SpanAttrs,
41
41
  fn: (span: any) => Promise<T>,
42
- _options?: WithSpanOptions
42
+ _options?: WithSpanOptions,
43
43
  ): Promise<T> {
44
44
  return await fn(noopSpan)
45
45
  }
@@ -52,7 +52,7 @@ export function withSyncSpan<T>(
52
52
  name: string,
53
53
  attrs: SpanAttrs,
54
54
  fn: (span: any) => T,
55
- _options?: WithSpanOptions
55
+ _options?: WithSpanOptions,
56
56
  ): T {
57
57
  return fn(noopSpan)
58
58
  }
package/src/types.ts CHANGED
@@ -2,7 +2,7 @@ import type {
2
2
  Collection,
3
3
  MutationFnParams,
4
4
  PendingMutation,
5
- } from "@tanstack/db"
5
+ } from '@tanstack/db'
6
6
 
7
7
  // Extended mutation function that includes idempotency key
8
8
  export type OfflineMutationFnParams<
@@ -12,7 +12,7 @@ export type OfflineMutationFnParams<
12
12
  }
13
13
 
14
14
  export type OfflineMutationFn<T extends object = Record<string, unknown>> = (
15
- params: OfflineMutationFnParams<T>
15
+ params: OfflineMutationFnParams<T>,
16
16
  ) => Promise<any>
17
17
 
18
18
  // Simplified mutation structure for serialization
@@ -95,7 +95,7 @@ export interface OfflineConfig {
95
95
  maxConcurrency?: number
96
96
  jitter?: boolean
97
97
  beforeRetry?: (
98
- transactions: Array<OfflineTransaction>
98
+ transactions: Array<OfflineTransaction>,
99
99
  ) => Array<OfflineTransaction>
100
100
  onUnknownMutationFn?: (name: string, tx: OfflineTransaction) => void
101
101
  onLeadershipChange?: (isLeader: boolean) => void