@quantform/core 0.7.22 → 0.7.25
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/lib/app.d.ts +12 -0
- package/lib/app.d.ts.map +1 -0
- package/lib/app.js +35 -0
- package/lib/cli/build.d.ts.map +1 -1
- package/lib/cli/build.js +8 -18
- package/lib/cli/index.js +3 -12
- package/lib/cli/internal/script.d.ts +1 -1
- package/lib/cli/internal/script.d.ts.map +1 -1
- package/lib/cli/internal/script.js +8 -28
- package/lib/cli/live.js +10 -22
- package/lib/cli/paper.js +10 -22
- package/lib/cli/replay.d.ts.map +1 -1
- package/lib/cli/replay.js +15 -26
- package/lib/index.d.ts +1 -6
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -6
- package/lib/make-test-module.d.ts +1 -6
- package/lib/make-test-module.d.ts.map +1 -1
- package/lib/make-test-module.js +19 -30
- package/lib/module.d.ts.map +1 -1
- package/lib/module.js +9 -24
- package/lib/module.spec.js +8 -17
- package/lib/replay/use-replay-options.d.ts +5 -4
- package/lib/replay/use-replay-options.d.ts.map +1 -1
- package/lib/replay/use-replay-options.js +5 -1
- package/lib/replay/use-replay-scheduler.d.ts +7 -6
- package/lib/replay/use-replay-scheduler.d.ts.map +1 -1
- package/lib/replay/use-replay-scheduler.js +64 -70
- package/lib/replay/use-replay-storage-buffer.d.ts +3 -2
- package/lib/replay/use-replay-storage-buffer.d.ts.map +1 -1
- package/lib/replay/use-replay-storage-buffer.js +12 -23
- package/lib/replay/use-replay-storage-cursor.d.ts +9 -8
- package/lib/replay/use-replay-storage-cursor.d.ts.map +1 -1
- package/lib/replay/use-replay-storage-cursor.js +17 -25
- package/lib/replay/use-replay-storage.d.ts +5 -4
- package/lib/replay/use-replay-storage.d.ts.map +1 -1
- package/lib/replay/use-replay-storage.js +32 -39
- package/lib/session/use-session-storage.d.ts +1 -1
- package/lib/session/use-session-storage.d.ts.map +1 -1
- package/lib/session/use-session-storage.js +8 -5
- package/lib/shared/environment.js +1 -1
- package/lib/shared/index.d.ts +0 -1
- package/lib/shared/index.d.ts.map +1 -1
- package/lib/shared/index.js +0 -1
- package/lib/simulator/use-simulator.spec.js +17 -30
- package/lib/storage/in-memory/in-memory-storage.d.ts.map +1 -1
- package/lib/storage/in-memory/in-memory-storage.factory.js +2 -2
- package/lib/storage/in-memory/in-memory-storage.js +56 -55
- package/lib/storage/in-memory/in-memory-storage.spec.js +90 -100
- package/lib/storage/storage.d.ts +9 -8
- package/lib/storage/storage.d.ts.map +1 -1
- package/lib/storage/storage.js +8 -2
- package/lib/storage/use-cache.d.ts +1 -1
- package/lib/storage/use-cache.d.ts.map +1 -1
- package/lib/storage/use-cache.js +5 -5
- package/lib/storage/use-cache.spec.js +14 -25
- package/lib/storage/use-storage.d.ts +1 -1
- package/lib/storage/use-storage.d.ts.map +1 -1
- package/lib/storage/use-storage.js +9 -6
- package/lib/use-execution-mode.js +2 -2
- package/lib/use-hash.spec.js +3 -6
- package/lib/use-logger.d.ts +1 -1
- package/lib/use-logger.d.ts.map +1 -1
- package/lib/use-logger.js +10 -7
- package/lib/use-memo.spec.js +14 -25
- package/lib/use-socket.d.ts +3 -2
- package/lib/use-socket.d.ts.map +1 -1
- package/lib/use-socket.js +2 -2
- package/lib/use-timestamp.d.ts +14 -1
- package/lib/use-timestamp.d.ts.map +1 -1
- package/lib/use-timestamp.js +30 -3
- package/lib/with-request.d.ts +2 -1
- package/lib/with-request.d.ts.map +1 -1
- package/lib/with-request.js +4 -13
- package/package.json +6 -10
- package/src/app.ts +52 -0
- package/src/cli/build.ts +11 -6
- package/src/cli/internal/script.ts +25 -54
- package/src/cli/replay.ts +13 -2
- package/src/index.ts +1 -6
- package/src/make-test-module.ts +13 -21
- package/src/module.ts +0 -3
- package/src/replay/use-replay-options.ts +7 -3
- package/src/replay/use-replay-scheduler.ts +75 -67
- package/src/replay/use-replay-storage-buffer.ts +2 -1
- package/src/replay/use-replay-storage-cursor.ts +33 -28
- package/src/replay/use-replay-storage.ts +36 -27
- package/src/session/use-session-storage.ts +7 -5
- package/src/shared/index.ts +0 -1
- package/src/storage/in-memory/in-memory-storage.spec.ts +55 -54
- package/src/storage/in-memory/in-memory-storage.ts +24 -7
- package/src/storage/storage.ts +16 -7
- package/src/storage/use-cache.ts +4 -4
- package/src/storage/use-storage.ts +8 -6
- package/src/use-hash.spec.ts +3 -6
- package/src/use-logger.ts +9 -6
- package/src/use-socket.ts +5 -5
- package/src/use-timestamp.ts +41 -3
- package/src/with-request.ts +3 -3
- package/lib/asset/asset.d.ts +0 -41
- package/lib/asset/asset.d.ts.map +0 -1
- package/lib/asset/asset.js +0 -76
- package/lib/asset/asset.spec.d.ts +0 -2
- package/lib/asset/asset.spec.d.ts.map +0 -1
- package/lib/asset/asset.spec.js +0 -54
- package/lib/asset/index.d.ts +0 -2
- package/lib/asset/index.d.ts.map +0 -1
- package/lib/asset/index.js +0 -17
- package/lib/component/distinct-until-timesamp-changed.d.ts +0 -5
- package/lib/component/distinct-until-timesamp-changed.d.ts.map +0 -1
- package/lib/component/distinct-until-timesamp-changed.js +0 -9
- package/lib/component/error.d.ts +0 -17
- package/lib/component/error.d.ts.map +0 -1
- package/lib/component/error.js +0 -33
- package/lib/component/index.d.ts +0 -8
- package/lib/component/index.d.ts.map +0 -1
- package/lib/component/index.js +0 -23
- package/lib/component/ohlc-operator.d.ts +0 -11
- package/lib/component/ohlc-operator.d.ts.map +0 -1
- package/lib/component/ohlc-operator.js +0 -69
- package/lib/component/ohlc-operator.spec.d.ts +0 -2
- package/lib/component/ohlc-operator.spec.d.ts.map +0 -1
- package/lib/component/ohlc-operator.spec.js +0 -110
- package/lib/component/ohlc.d.ts +0 -12
- package/lib/component/ohlc.d.ts.map +0 -1
- package/lib/component/ohlc.js +0 -20
- package/lib/component/ohlc.spec.d.ts +0 -2
- package/lib/component/ohlc.spec.d.ts.map +0 -1
- package/lib/component/ohlc.spec.js +0 -25
- package/lib/component/timeframe.d.ts +0 -15
- package/lib/component/timeframe.d.ts.map +0 -1
- package/lib/component/timeframe.js +0 -21
- package/lib/core.d.ts +0 -3
- package/lib/core.d.ts.map +0 -1
- package/lib/core.js +0 -17
- package/lib/instrument/commission/commission.d.ts +0 -16
- package/lib/instrument/commission/commission.d.ts.map +0 -1
- package/lib/instrument/commission/commission.js +0 -28
- package/lib/instrument/commission/commission.spec.d.ts +0 -2
- package/lib/instrument/commission/commission.spec.d.ts.map +0 -1
- package/lib/instrument/commission/commission.spec.js +0 -30
- package/lib/instrument/index.d.ts +0 -3
- package/lib/instrument/index.d.ts.map +0 -1
- package/lib/instrument/index.js +0 -18
- package/lib/instrument/instrument.d.ts +0 -28
- package/lib/instrument/instrument.d.ts.map +0 -1
- package/lib/instrument/instrument.js +0 -53
- package/lib/instrument/instrument.spec.d.ts +0 -2
- package/lib/instrument/instrument.spec.d.ts.map +0 -1
- package/lib/instrument/instrument.spec.js +0 -51
- package/lib/operators.d.ts +0 -5
- package/lib/operators.d.ts.map +0 -1
- package/lib/operators.js +0 -16
- package/lib/shared/datetime.d.ts +0 -3
- package/lib/shared/datetime.d.ts.map +0 -1
- package/lib/shared/datetime.js +0 -7
- package/lib/strategy.d.ts +0 -15
- package/lib/strategy.d.ts.map +0 -1
- package/lib/strategy.js +0 -26
- package/lib/strategy.spec.d.ts +0 -2
- package/lib/strategy.spec.d.ts.map +0 -1
- package/lib/strategy.spec.js +0 -34
- package/lib/when-socket.d.ts +0 -8
- package/lib/when-socket.d.ts.map +0 -1
- package/lib/when-socket.js +0 -53
- package/lib/with-memo.d.ts +0 -5
- package/lib/with-memo.d.ts.map +0 -1
- package/lib/with-memo.js +0 -20
- package/lib/with-memo.spec.d.ts +0 -2
- package/lib/with-memo.spec.d.ts.map +0 -1
- package/lib/with-memo.spec.js +0 -47
- package/src/asset/asset.spec.ts +0 -70
- package/src/asset/asset.ts +0 -89
- package/src/asset/index.ts +0 -1
- package/src/component/distinct-until-timesamp-changed.ts +0 -11
- package/src/component/error.ts +0 -32
- package/src/component/index.ts +0 -7
- package/src/component/ohlc-operator.spec.ts +0 -125
- package/src/component/ohlc-operator.ts +0 -122
- package/src/component/ohlc.spec.ts +0 -30
- package/src/component/ohlc.ts +0 -18
- package/src/component/timeframe.ts +0 -17
- package/src/core.ts +0 -16
- package/src/instrument/commission/commission.spec.ts +0 -35
- package/src/instrument/commission/commission.ts +0 -27
- package/src/instrument/index.ts +0 -2
- package/src/instrument/instrument.spec.ts +0 -76
- package/src/instrument/instrument.ts +0 -65
- package/src/operators.ts +0 -18
- package/src/shared/datetime.ts +0 -5
- package/src/strategy.spec.ts +0 -42
- package/src/strategy.ts +0 -36
- package/src/when-socket.ts +0 -61
- package/src/with-memo.spec.ts +0 -46
- package/src/with-memo.ts +0 -33
package/src/make-test-module.ts
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
|
-
import { Observable
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
2
|
|
|
3
|
-
import { core } from '@lib/core';
|
|
4
3
|
import { Dependency, Module } from '@lib/module';
|
|
5
4
|
|
|
5
|
+
import { InMemoryStorageFactory, useStorageFactory } from './storage';
|
|
6
|
+
import { useExecutionMode } from './use-execution-mode';
|
|
7
|
+
import { ConsoleLoggerFactory, logger } from './use-logger';
|
|
8
|
+
import { useMemo } from './use-memo';
|
|
9
|
+
|
|
6
10
|
export async function makeTestModule(dependencies: Dependency[]) {
|
|
7
|
-
const module = new Module([
|
|
11
|
+
const module = new Module([
|
|
12
|
+
useMemo.options(),
|
|
13
|
+
logger(new ConsoleLoggerFactory()),
|
|
14
|
+
useExecutionMode.paperOptions({ recording: false }),
|
|
15
|
+
useStorageFactory.options(new InMemoryStorageFactory()),
|
|
16
|
+
...dependencies
|
|
17
|
+
]);
|
|
8
18
|
|
|
9
19
|
const { act } = await module.awake();
|
|
10
20
|
|
|
@@ -14,11 +24,6 @@ export async function makeTestModule(dependencies: Dependency[]) {
|
|
|
14
24
|
};
|
|
15
25
|
}
|
|
16
26
|
|
|
17
|
-
type MockableFunction = (...args: any[]) => any;
|
|
18
|
-
|
|
19
|
-
export const mockedFunc = <Func extends MockableFunction>(mockedFunc: Func) =>
|
|
20
|
-
mockedFunc as jest.MockedFunction<typeof mockedFunc>;
|
|
21
|
-
|
|
22
27
|
export function toArray<T>(observable: Observable<T>) {
|
|
23
28
|
const array = Array.of<T | Error>();
|
|
24
29
|
|
|
@@ -47,16 +52,3 @@ export function toArray<T>(observable: Observable<T>) {
|
|
|
47
52
|
}
|
|
48
53
|
|
|
49
54
|
export type InferObservableType<T> = T extends Observable<infer U> ? U : never;
|
|
50
|
-
|
|
51
|
-
export function mockSubject<
|
|
52
|
-
T extends jest.FunctionProperties<Required<T>>,
|
|
53
|
-
M extends keyof jest.FunctionProperties<Required<T>>
|
|
54
|
-
>(object: T, method: M) {
|
|
55
|
-
const subject = new Subject<
|
|
56
|
-
InferObservableType<ReturnType<jest.FunctionProperties<Required<T>>[M]>>
|
|
57
|
-
>();
|
|
58
|
-
|
|
59
|
-
jest.spyOn<T, M>(object, method).mockReturnValue(subject.asObservable() as any);
|
|
60
|
-
|
|
61
|
-
return subject;
|
|
62
|
-
}
|
package/src/module.ts
CHANGED
|
@@ -37,9 +37,6 @@ function missingInjectionTokenError(token: InjectionToken) {
|
|
|
37
37
|
return new Error(`Unable to resolve unregistered dependency: ${token.toString()}`);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
/**
|
|
41
|
-
*
|
|
42
|
-
*/
|
|
43
40
|
let moduleLocalStorage = new AsyncLocalStorage<Module>();
|
|
44
41
|
|
|
45
42
|
export function setAsyncLocalStorage(als: AsyncLocalStorage<Module>) {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Dependency, useContext } from '@lib/module';
|
|
2
|
+
import { Timestamp } from '@lib/use-timestamp';
|
|
2
3
|
|
|
3
4
|
const injectionToken = Symbol('replay-options');
|
|
4
5
|
|
|
5
6
|
type ReplayOptions = {
|
|
6
|
-
from:
|
|
7
|
-
to:
|
|
7
|
+
from: Timestamp<'ns'>;
|
|
8
|
+
to: Timestamp<'ns'>;
|
|
8
9
|
limit?: number;
|
|
9
10
|
storage?: string;
|
|
10
11
|
};
|
|
@@ -13,7 +14,10 @@ type ReplayOptions = {
|
|
|
13
14
|
*
|
|
14
15
|
*/
|
|
15
16
|
export function replayOptions(
|
|
16
|
-
options: Omit<ReplayOptions, 'from' | 'to'> & {
|
|
17
|
+
options: Omit<ReplayOptions, 'from' | 'to'> & {
|
|
18
|
+
from: Timestamp<'ns'>;
|
|
19
|
+
to: Timestamp<'ns'>;
|
|
20
|
+
}
|
|
17
21
|
): Dependency {
|
|
18
22
|
return {
|
|
19
23
|
provide: injectionToken,
|
|
@@ -1,97 +1,105 @@
|
|
|
1
1
|
import { defer, filter, map, Observable, Subject } from 'rxjs';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { useMemo } from '@lib/use-memo';
|
|
4
|
+
import { Timestamp } from '@lib/use-timestamp';
|
|
4
5
|
|
|
5
6
|
import { useReplayOptions } from './use-replay-options';
|
|
6
7
|
import { useReplayStorageBuffer } from './use-replay-storage-buffer';
|
|
7
8
|
import { ReplayQuery, useReplayStorageCursor } from './use-replay-storage-cursor';
|
|
8
9
|
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
export function useReplayScheduler() {
|
|
11
|
+
return useMemo(() => {
|
|
12
|
+
const { from } = useReplayOptions();
|
|
13
|
+
const { get, cursor } = useReplayStorageCursor();
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
let timestamp = from;
|
|
16
|
+
let stopAcquire = 1;
|
|
17
|
+
let processing = false;
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
const stream$ = new Subject<
|
|
20
|
+
[
|
|
21
|
+
ReturnType<typeof useReplayStorageBuffer<any>>,
|
|
22
|
+
{ timestamp: Timestamp<'ns'>; payload: any }
|
|
23
|
+
]
|
|
24
|
+
>();
|
|
20
25
|
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
const processNext = async () => {
|
|
27
|
+
const storage = await cursor();
|
|
23
28
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
if (!storage || !storage.peek()) {
|
|
30
|
+
stream$.complete();
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const sample = storage.dequeue();
|
|
28
35
|
|
|
29
|
-
|
|
36
|
+
timestamp = sample.timestamp;
|
|
30
37
|
|
|
31
|
-
|
|
38
|
+
stream$.next([storage, sample]);
|
|
32
39
|
|
|
33
|
-
|
|
40
|
+
return true;
|
|
41
|
+
};
|
|
34
42
|
|
|
35
|
-
|
|
36
|
-
|
|
43
|
+
const next = async () => {
|
|
44
|
+
if (processing) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
37
47
|
|
|
38
|
-
|
|
39
|
-
if (processing) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
48
|
+
processing = true;
|
|
42
49
|
|
|
43
|
-
|
|
50
|
+
while (stopAcquire === 0) {
|
|
51
|
+
if (!(await processNext())) {
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
44
54
|
|
|
45
|
-
|
|
46
|
-
if (!(await processNext())) {
|
|
47
|
-
break;
|
|
55
|
+
await new Promise(it => setImmediate(it));
|
|
48
56
|
}
|
|
49
57
|
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
processing = false;
|
|
54
|
-
};
|
|
58
|
+
processing = false;
|
|
59
|
+
};
|
|
55
60
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
const tryContinue = () => {
|
|
62
|
+
if (stopAcquire === 0) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
60
65
|
|
|
61
|
-
|
|
66
|
+
stopAcquire--;
|
|
62
67
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
if (stopAcquire === 0) {
|
|
69
|
+
next();
|
|
70
|
+
}
|
|
71
|
+
};
|
|
67
72
|
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
return {
|
|
74
|
+
stream: stream$.asObservable(),
|
|
70
75
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
timestamp() {
|
|
77
|
+
return timestamp;
|
|
78
|
+
},
|
|
74
79
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
80
|
+
stop() {
|
|
81
|
+
stopAcquire++;
|
|
82
|
+
},
|
|
78
83
|
|
|
79
|
-
|
|
84
|
+
tryContinue,
|
|
80
85
|
|
|
81
|
-
|
|
82
|
-
|
|
86
|
+
watch<T>(
|
|
87
|
+
query: ReplayQuery<T>
|
|
88
|
+
): Observable<{ timestamp: Timestamp<'ns'>; payload: T }> {
|
|
89
|
+
const storage = get<T>(query);
|
|
83
90
|
|
|
84
|
-
|
|
85
|
-
|
|
91
|
+
return defer(() => {
|
|
92
|
+
tryContinue();
|
|
86
93
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
});
|
|
94
|
+
return stream$.pipe(
|
|
95
|
+
filter(([cur]) => cur === storage),
|
|
96
|
+
map(([, it]) => ({
|
|
97
|
+
timestamp: it.timestamp,
|
|
98
|
+
payload: it.payload as T
|
|
99
|
+
}))
|
|
100
|
+
);
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
}, [useReplayScheduler.name]);
|
|
105
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { between } from '@lib/storage';
|
|
2
|
+
import { Timestamp } from '@lib/use-timestamp';
|
|
2
3
|
|
|
3
4
|
import { useReplayOptions } from './use-replay-options';
|
|
4
5
|
import { ReplayQuery } from './use-replay-storage-cursor';
|
|
@@ -6,7 +7,7 @@ import { ReplayQuery } from './use-replay-storage-cursor';
|
|
|
6
7
|
export function useReplayStorageBuffer<T>(storage: ReplayQuery<T>) {
|
|
7
8
|
const { from, to, limit } = useReplayOptions();
|
|
8
9
|
|
|
9
|
-
let page: Array<{ timestamp:
|
|
10
|
+
let page: Array<{ timestamp: Timestamp<'ns'>; payload: T }> = [];
|
|
10
11
|
let index = 0;
|
|
11
12
|
let completed = false;
|
|
12
13
|
let count = 0;
|
|
@@ -1,48 +1,53 @@
|
|
|
1
1
|
import { Query, QueryObject } from '@lib/storage';
|
|
2
|
-
import {
|
|
2
|
+
import { useMemo } from '@lib/use-memo';
|
|
3
|
+
import { Timestamp } from '@lib/use-timestamp';
|
|
3
4
|
|
|
4
5
|
import { useReplayStorageBuffer } from './use-replay-storage-buffer';
|
|
5
6
|
|
|
6
7
|
export interface ReplayQuery<V> {
|
|
7
8
|
query(
|
|
8
9
|
query: Query<QueryObject> & {
|
|
9
|
-
where: {
|
|
10
|
+
where: {
|
|
11
|
+
timestamp: { type: 'between'; min: Timestamp<'ns'>; max: Timestamp<'ns'> };
|
|
12
|
+
};
|
|
10
13
|
}
|
|
11
|
-
): Promise<{ timestamp:
|
|
14
|
+
): Promise<{ timestamp: Timestamp<'ns'>; payload: V }[]>;
|
|
12
15
|
}
|
|
13
16
|
|
|
14
|
-
export
|
|
15
|
-
|
|
17
|
+
export function useReplayStorageCursor() {
|
|
18
|
+
return useMemo(() => {
|
|
19
|
+
const cursors = Array.of<ReturnType<typeof useReplayStorageBuffer<any>>>();
|
|
16
20
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
return {
|
|
22
|
+
get<T>(query: ReplayQuery<T>) {
|
|
23
|
+
const buffer = useReplayStorageBuffer<T>(query);
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
cursors.push(buffer);
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
return buffer;
|
|
28
|
+
},
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
async cursor() {
|
|
31
|
+
let current: ReturnType<typeof useReplayStorageBuffer<any>> | undefined;
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
+
for (const cursor of cursors) {
|
|
34
|
+
if (cursor.completed()) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
33
37
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
if (cursor.size() == 0) {
|
|
39
|
+
await cursor.fetchNextPage();
|
|
40
|
+
}
|
|
37
41
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
if (cursor.peek()) {
|
|
43
|
+
if (!current || current.peek().timestamp > cursor.peek().timestamp) {
|
|
44
|
+
current = cursor;
|
|
45
|
+
}
|
|
41
46
|
}
|
|
42
47
|
}
|
|
43
|
-
}
|
|
44
48
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
});
|
|
49
|
+
return current;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}, [useReplayStorageCursor.name]);
|
|
53
|
+
}
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
import { Uri } from '@lib/uri';
|
|
14
14
|
import { useLogger } from '@lib/use-logger';
|
|
15
15
|
import { useMemo } from '@lib/use-memo';
|
|
16
|
+
import { ns, Timestamp } from '@lib/use-timestamp';
|
|
16
17
|
|
|
17
18
|
import { useReplayOptions } from './use-replay-options';
|
|
18
19
|
import { useReplayScheduler } from './use-replay-scheduler';
|
|
@@ -20,17 +21,21 @@ import { useReplayScheduler } from './use-replay-scheduler';
|
|
|
20
21
|
export type ReplayStorageQuery<V> = {
|
|
21
22
|
sync: <T extends QueryObjectType<K>, K extends QueryObject>(
|
|
22
23
|
query: Query<InferQueryObject<T>> & {
|
|
23
|
-
where: {
|
|
24
|
+
where: {
|
|
25
|
+
timestamp: { type: 'between'; min: Timestamp<'ns'>; max: Timestamp<'ns'> };
|
|
26
|
+
};
|
|
24
27
|
},
|
|
25
|
-
storage: {
|
|
28
|
+
storage: {
|
|
29
|
+
save: (objects: { timestamp: Timestamp<'ns'>; payload: V }[]) => Promise<void>;
|
|
30
|
+
}
|
|
26
31
|
) => Promise<void>;
|
|
27
32
|
};
|
|
28
33
|
|
|
29
34
|
const storageIndexObject = Storage.createObject('index://range', {
|
|
30
|
-
timestamp: '
|
|
35
|
+
timestamp: 'bigint',
|
|
31
36
|
uri: 'string',
|
|
32
|
-
min: '
|
|
33
|
-
max: '
|
|
37
|
+
min: 'bigint',
|
|
38
|
+
max: 'bigint'
|
|
34
39
|
});
|
|
35
40
|
|
|
36
41
|
export function useReplayStorage<V, P extends Record<string, string | number>>(
|
|
@@ -38,16 +43,16 @@ export function useReplayStorage<V, P extends Record<string, string | number>>(
|
|
|
38
43
|
{ sync }: ReplayStorageQuery<V>
|
|
39
44
|
) {
|
|
40
45
|
const { watch } = useReplayScheduler();
|
|
41
|
-
const { info } = useLogger(useReplayStorage.name);
|
|
46
|
+
const { info, error } = useLogger(useReplayStorage.name);
|
|
42
47
|
const options = useReplayOptions();
|
|
43
48
|
const storage = useStorage([options.storage]);
|
|
44
49
|
const storageObjectKey = uri.query;
|
|
45
50
|
const storageObject = Storage.createObject(storageObjectKey, {
|
|
46
|
-
timestamp: '
|
|
51
|
+
timestamp: 'bigint',
|
|
47
52
|
payload: 'string'
|
|
48
53
|
});
|
|
49
54
|
|
|
50
|
-
const id = hashCode(storageObjectKey);
|
|
55
|
+
const id = ns(hashCode(storageObjectKey));
|
|
51
56
|
|
|
52
57
|
return {
|
|
53
58
|
watch: () =>
|
|
@@ -65,26 +70,30 @@ export function useReplayStorage<V, P extends Record<string, string | number>>(
|
|
|
65
70
|
if (!index || min < index.min || max > index.max) {
|
|
66
71
|
info(`fetching replay for ${storageObjectKey} started`);
|
|
67
72
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
try {
|
|
74
|
+
await sync(query, {
|
|
75
|
+
async save(objects) {
|
|
76
|
+
await storage.save(
|
|
77
|
+
storageObject,
|
|
78
|
+
objects.map(it => ({
|
|
79
|
+
timestamp: it.timestamp,
|
|
80
|
+
payload: JSON.stringify(it.payload)
|
|
81
|
+
}))
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
79
85
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
await storage.save(storageIndexObject, [
|
|
87
|
+
{
|
|
88
|
+
timestamp: id,
|
|
89
|
+
max,
|
|
90
|
+
min,
|
|
91
|
+
uri: storageObjectKey
|
|
92
|
+
}
|
|
93
|
+
]);
|
|
94
|
+
} catch (err) {
|
|
95
|
+
error(`fetching replay for ${storageObjectKey} failed: ${err}`);
|
|
96
|
+
}
|
|
88
97
|
|
|
89
98
|
info(`fetching replay for ${storageObjectKey} finished`);
|
|
90
99
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { useSession } from '@lib/session';
|
|
2
2
|
import { useStorage } from '@lib/storage';
|
|
3
|
-
import {
|
|
3
|
+
import { useMemo } from '@lib/use-memo';
|
|
4
4
|
|
|
5
|
-
export
|
|
6
|
-
|
|
5
|
+
export function useSessionStorage() {
|
|
6
|
+
return useMemo(() => {
|
|
7
|
+
const { id } = useSession();
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
});
|
|
9
|
+
return useStorage(['session', id]);
|
|
10
|
+
}, [useSessionStorage.name]);
|
|
11
|
+
}
|
package/src/shared/index.ts
CHANGED