@tanstack/offline-transactions 0.1.2 → 1.0.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.
- package/dist/cjs/api/OfflineAction.cjs +8 -20
- package/dist/cjs/api/OfflineAction.cjs.map +1 -1
- package/dist/cjs/api/OfflineTransaction.cjs +1 -9
- package/dist/cjs/api/OfflineTransaction.cjs.map +1 -1
- package/dist/cjs/executor/TransactionExecutor.cjs +0 -15
- package/dist/cjs/executor/TransactionExecutor.cjs.map +1 -1
- package/dist/cjs/outbox/OutboxManager.cjs +3 -3
- package/dist/cjs/outbox/OutboxManager.cjs.map +1 -1
- package/dist/cjs/outbox/OutboxManager.d.cts +1 -1
- package/dist/cjs/outbox/TransactionSerializer.cjs +1 -0
- package/dist/cjs/outbox/TransactionSerializer.cjs.map +1 -1
- package/dist/cjs/outbox/TransactionSerializer.d.cts +1 -1
- package/dist/cjs/telemetry/tracer.cjs +17 -81
- package/dist/cjs/telemetry/tracer.cjs.map +1 -1
- package/dist/cjs/telemetry/tracer.d.cts +9 -8
- package/dist/cjs/types.cjs.map +1 -1
- package/dist/cjs/types.d.cts +1 -1
- package/dist/esm/api/OfflineAction.js +8 -20
- package/dist/esm/api/OfflineAction.js.map +1 -1
- package/dist/esm/api/OfflineTransaction.js +1 -9
- package/dist/esm/api/OfflineTransaction.js.map +1 -1
- package/dist/esm/executor/TransactionExecutor.js +0 -15
- package/dist/esm/executor/TransactionExecutor.js.map +1 -1
- package/dist/esm/outbox/OutboxManager.d.ts +1 -1
- package/dist/esm/outbox/OutboxManager.js +3 -3
- package/dist/esm/outbox/OutboxManager.js.map +1 -1
- package/dist/esm/outbox/TransactionSerializer.d.ts +1 -1
- package/dist/esm/outbox/TransactionSerializer.js +1 -0
- package/dist/esm/outbox/TransactionSerializer.js.map +1 -1
- package/dist/esm/telemetry/tracer.d.ts +9 -8
- package/dist/esm/telemetry/tracer.js +17 -81
- package/dist/esm/telemetry/tracer.js.map +1 -1
- package/dist/esm/types.d.ts +1 -1
- package/dist/esm/types.js.map +1 -1
- package/package.json +4 -6
- package/src/api/OfflineAction.ts +9 -25
- package/src/api/OfflineTransaction.ts +1 -12
- package/src/executor/TransactionExecutor.ts +1 -27
- package/src/outbox/OutboxManager.ts +2 -1
- package/src/outbox/TransactionSerializer.ts +6 -2
- package/src/telemetry/tracer.ts +22 -107
- package/src/types.ts +2 -1
|
@@ -1,35 +1,12 @@
|
|
|
1
|
-
import { createTraceState } from "@opentelemetry/api"
|
|
2
1
|
import { DefaultRetryPolicy } from "../retry/RetryPolicy"
|
|
3
2
|
import { NonRetriableError } from "../types"
|
|
4
3
|
import { withNestedSpan } from "../telemetry/tracer"
|
|
5
|
-
import type { SpanContext } from "@opentelemetry/api"
|
|
6
4
|
import type { KeyScheduler } from "./KeyScheduler"
|
|
7
5
|
import type { OutboxManager } from "../outbox/OutboxManager"
|
|
8
|
-
import type {
|
|
9
|
-
OfflineConfig,
|
|
10
|
-
OfflineTransaction,
|
|
11
|
-
SerializedSpanContext,
|
|
12
|
-
} from "../types"
|
|
6
|
+
import type { OfflineConfig, OfflineTransaction } from "../types"
|
|
13
7
|
|
|
14
8
|
const HANDLED_EXECUTION_ERROR = Symbol(`HandledExecutionError`)
|
|
15
9
|
|
|
16
|
-
function toSpanContext(
|
|
17
|
-
serialized?: SerializedSpanContext
|
|
18
|
-
): SpanContext | undefined {
|
|
19
|
-
if (!serialized) {
|
|
20
|
-
return undefined
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
traceId: serialized.traceId,
|
|
25
|
-
spanId: serialized.spanId,
|
|
26
|
-
traceFlags: serialized.traceFlags,
|
|
27
|
-
traceState: serialized.traceState
|
|
28
|
-
? createTraceState(serialized.traceState)
|
|
29
|
-
: undefined,
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
10
|
export class TransactionExecutor {
|
|
34
11
|
private scheduler: KeyScheduler
|
|
35
12
|
private outbox: OutboxManager
|
|
@@ -131,9 +108,6 @@ export class TransactionExecutor {
|
|
|
131
108
|
;(err as any)[HANDLED_EXECUTION_ERROR] = true
|
|
132
109
|
throw err
|
|
133
110
|
}
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
parentContext: toSpanContext(transaction.spanContext),
|
|
137
111
|
}
|
|
138
112
|
)
|
|
139
113
|
} catch (error) {
|
|
@@ -10,7 +10,8 @@ export class OutboxManager {
|
|
|
10
10
|
|
|
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
15
|
) {
|
|
15
16
|
this.storage = storage
|
|
16
17
|
this.serializer = new TransactionSerializer(collections)
|
|
@@ -7,10 +7,14 @@ import type {
|
|
|
7
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
|
|
11
|
+
private collections: Record<string, Collection<any, any, any, any, any>>
|
|
11
12
|
private collectionIdToKey: Map<string, string>
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
15
|
+
constructor(
|
|
16
|
+
collections: Record<string, Collection<any, any, any, any, any>>
|
|
17
|
+
) {
|
|
14
18
|
this.collections = collections
|
|
15
19
|
// Create reverse lookup from collection.id to registry key
|
|
16
20
|
this.collectionIdToKey = new Map()
|
package/src/telemetry/tracer.ts
CHANGED
|
@@ -1,28 +1,23 @@
|
|
|
1
|
-
import { SpanStatusCode, context, trace } from "@opentelemetry/api"
|
|
2
|
-
import type { Span, SpanContext } from "@opentelemetry/api"
|
|
3
|
-
|
|
4
|
-
const TRACER = trace.getTracer(`@tanstack/offline-transactions`, `0.0.1`)
|
|
5
|
-
|
|
6
1
|
export interface SpanAttrs {
|
|
7
2
|
[key: string]: string | number | boolean | undefined
|
|
8
3
|
}
|
|
9
4
|
|
|
10
5
|
interface WithSpanOptions {
|
|
11
|
-
parentContext?:
|
|
6
|
+
parentContext?: any
|
|
12
7
|
}
|
|
13
8
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
9
|
+
// No-op span implementation
|
|
10
|
+
const noopSpan = {
|
|
11
|
+
setAttribute: () => {},
|
|
12
|
+
setAttributes: () => {},
|
|
13
|
+
setStatus: () => {},
|
|
14
|
+
recordException: () => {},
|
|
15
|
+
end: () => {},
|
|
21
16
|
}
|
|
22
17
|
|
|
23
18
|
/**
|
|
24
19
|
* Lightweight span wrapper with error handling.
|
|
25
|
-
*
|
|
20
|
+
* No-op implementation - telemetry has been removed.
|
|
26
21
|
*
|
|
27
22
|
* By default, creates spans at the current context level (siblings).
|
|
28
23
|
* Use withNestedSpan if you want parent-child relationships.
|
|
@@ -30,122 +25,42 @@ function getParentContext(options?: WithSpanOptions) {
|
|
|
30
25
|
export async function withSpan<T>(
|
|
31
26
|
name: string,
|
|
32
27
|
attrs: SpanAttrs,
|
|
33
|
-
fn: (span:
|
|
34
|
-
|
|
28
|
+
fn: (span: any) => Promise<T>,
|
|
29
|
+
_options?: WithSpanOptions
|
|
35
30
|
): Promise<T> {
|
|
36
|
-
|
|
37
|
-
const span = TRACER.startSpan(name, undefined, parentCtx)
|
|
38
|
-
|
|
39
|
-
// Filter out undefined attributes
|
|
40
|
-
const filteredAttrs: Record<string, string | number | boolean> = {}
|
|
41
|
-
for (const [key, value] of Object.entries(attrs)) {
|
|
42
|
-
if (value !== undefined) {
|
|
43
|
-
filteredAttrs[key] = value
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
span.setAttributes(filteredAttrs)
|
|
48
|
-
|
|
49
|
-
try {
|
|
50
|
-
const result = await fn(span)
|
|
51
|
-
span.setStatus({ code: SpanStatusCode.OK })
|
|
52
|
-
return result
|
|
53
|
-
} catch (error) {
|
|
54
|
-
span.setStatus({
|
|
55
|
-
code: SpanStatusCode.ERROR,
|
|
56
|
-
message: error instanceof Error ? error.message : String(error),
|
|
57
|
-
})
|
|
58
|
-
span.recordException(error as Error)
|
|
59
|
-
throw error
|
|
60
|
-
} finally {
|
|
61
|
-
span.end()
|
|
62
|
-
}
|
|
31
|
+
return await fn(noopSpan)
|
|
63
32
|
}
|
|
64
33
|
|
|
65
34
|
/**
|
|
66
35
|
* Like withSpan but propagates context so child spans nest properly.
|
|
67
|
-
*
|
|
36
|
+
* No-op implementation - telemetry has been removed.
|
|
68
37
|
*/
|
|
69
38
|
export async function withNestedSpan<T>(
|
|
70
39
|
name: string,
|
|
71
40
|
attrs: SpanAttrs,
|
|
72
|
-
fn: (span:
|
|
73
|
-
|
|
41
|
+
fn: (span: any) => Promise<T>,
|
|
42
|
+
_options?: WithSpanOptions
|
|
74
43
|
): Promise<T> {
|
|
75
|
-
|
|
76
|
-
const span = TRACER.startSpan(name, undefined, parentCtx)
|
|
77
|
-
|
|
78
|
-
// Filter out undefined attributes
|
|
79
|
-
const filteredAttrs: Record<string, string | number | boolean> = {}
|
|
80
|
-
for (const [key, value] of Object.entries(attrs)) {
|
|
81
|
-
if (value !== undefined) {
|
|
82
|
-
filteredAttrs[key] = value
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
span.setAttributes(filteredAttrs)
|
|
87
|
-
|
|
88
|
-
// Set the span as active context so child spans nest properly
|
|
89
|
-
const ctx = trace.setSpan(parentCtx, span)
|
|
90
|
-
|
|
91
|
-
try {
|
|
92
|
-
// Execute the function within the span's context
|
|
93
|
-
const result = await context.with(ctx, () => fn(span))
|
|
94
|
-
span.setStatus({ code: SpanStatusCode.OK })
|
|
95
|
-
return result
|
|
96
|
-
} catch (error) {
|
|
97
|
-
span.setStatus({
|
|
98
|
-
code: SpanStatusCode.ERROR,
|
|
99
|
-
message: error instanceof Error ? error.message : String(error),
|
|
100
|
-
})
|
|
101
|
-
span.recordException(error as Error)
|
|
102
|
-
throw error
|
|
103
|
-
} finally {
|
|
104
|
-
span.end()
|
|
105
|
-
}
|
|
44
|
+
return await fn(noopSpan)
|
|
106
45
|
}
|
|
107
46
|
|
|
108
47
|
/**
|
|
109
48
|
* Creates a synchronous span for non-async operations
|
|
49
|
+
* No-op implementation - telemetry has been removed.
|
|
110
50
|
*/
|
|
111
51
|
export function withSyncSpan<T>(
|
|
112
52
|
name: string,
|
|
113
53
|
attrs: SpanAttrs,
|
|
114
|
-
fn: (span:
|
|
115
|
-
|
|
54
|
+
fn: (span: any) => T,
|
|
55
|
+
_options?: WithSpanOptions
|
|
116
56
|
): T {
|
|
117
|
-
|
|
118
|
-
const span = TRACER.startSpan(name, undefined, parentCtx)
|
|
119
|
-
|
|
120
|
-
// Filter out undefined attributes
|
|
121
|
-
const filteredAttrs: Record<string, string | number | boolean> = {}
|
|
122
|
-
for (const [key, value] of Object.entries(attrs)) {
|
|
123
|
-
if (value !== undefined) {
|
|
124
|
-
filteredAttrs[key] = value
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
span.setAttributes(filteredAttrs)
|
|
129
|
-
|
|
130
|
-
try {
|
|
131
|
-
const result = fn(span)
|
|
132
|
-
span.setStatus({ code: SpanStatusCode.OK })
|
|
133
|
-
return result
|
|
134
|
-
} catch (error) {
|
|
135
|
-
span.setStatus({
|
|
136
|
-
code: SpanStatusCode.ERROR,
|
|
137
|
-
message: error instanceof Error ? error.message : String(error),
|
|
138
|
-
})
|
|
139
|
-
span.recordException(error as Error)
|
|
140
|
-
throw error
|
|
141
|
-
} finally {
|
|
142
|
-
span.end()
|
|
143
|
-
}
|
|
57
|
+
return fn(noopSpan)
|
|
144
58
|
}
|
|
145
59
|
|
|
146
60
|
/**
|
|
147
61
|
* Get the current tracer instance
|
|
62
|
+
* No-op implementation - telemetry has been removed.
|
|
148
63
|
*/
|
|
149
64
|
export function getTracer() {
|
|
150
|
-
return
|
|
65
|
+
return null
|
|
151
66
|
}
|
package/src/types.ts
CHANGED
|
@@ -88,7 +88,8 @@ export interface StorageDiagnostic {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
export interface OfflineConfig {
|
|
91
|
-
|
|
91
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
92
|
+
collections: Record<string, Collection<any, any, any, any, any>>
|
|
92
93
|
mutationFns: Record<string, OfflineMutationFn>
|
|
93
94
|
storage?: StorageAdapter
|
|
94
95
|
maxConcurrency?: number
|