@quantform/core 0.7.0-beta.4 → 0.7.0-beta.41

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 (179) hide show
  1. package/dist/asset/asset.d.ts +3 -0
  2. package/dist/asset/asset.d.ts.map +1 -1
  3. package/dist/asset/asset.js +7 -1
  4. package/dist/cli/dev.d.ts.map +1 -1
  5. package/dist/cli/dev.js +3 -36
  6. package/dist/cli/internal/script.d.ts +8 -0
  7. package/dist/cli/internal/script.d.ts.map +1 -0
  8. package/dist/cli/internal/script.js +58 -0
  9. package/dist/cli/pull.d.ts.map +1 -1
  10. package/dist/cli/pull.js +4 -83
  11. package/dist/cli/replay.d.ts.map +1 -1
  12. package/dist/cli/replay.js +3 -35
  13. package/dist/cli/run.d.ts.map +1 -1
  14. package/dist/cli/run.js +3 -37
  15. package/dist/index.d.ts +5 -14
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +5 -14
  18. package/dist/instrument/instrument.d.ts +3 -0
  19. package/dist/instrument/instrument.d.ts.map +1 -1
  20. package/dist/instrument/instrument.js +7 -1
  21. package/dist/make-test-module.d.ts +3 -2
  22. package/dist/make-test-module.d.ts.map +1 -1
  23. package/dist/make-test-module.js +13 -2
  24. package/dist/operators.d.ts +5 -0
  25. package/dist/operators.d.ts.map +1 -0
  26. package/dist/operators.js +16 -0
  27. package/dist/replay/index.d.ts +6 -4
  28. package/dist/replay/index.d.ts.map +1 -1
  29. package/dist/replay/index.js +6 -4
  30. package/dist/replay/replay-guard.d.ts +10 -0
  31. package/dist/replay/replay-guard.d.ts.map +1 -0
  32. package/dist/replay/replay-guard.js +8 -0
  33. package/dist/replay/replay.d.ts +10 -0
  34. package/dist/replay/replay.d.ts.map +1 -0
  35. package/dist/replay/replay.js +9 -0
  36. package/dist/replay/use-replay-breakpoint.d.ts +3 -0
  37. package/dist/replay/use-replay-breakpoint.d.ts.map +1 -0
  38. package/dist/replay/use-replay-breakpoint.js +22 -0
  39. package/dist/replay/use-replay-manager.d.ts +12 -0
  40. package/dist/replay/use-replay-manager.d.ts.map +1 -0
  41. package/dist/replay/use-replay-manager.js +88 -0
  42. package/dist/replay/use-replay-storage-buffer.d.ts +15 -0
  43. package/dist/replay/use-replay-storage-buffer.d.ts.map +1 -0
  44. package/dist/replay/use-replay-storage-buffer.js +50 -0
  45. package/dist/replay/use-replay-storage.d.ts +11 -8
  46. package/dist/replay/use-replay-storage.d.ts.map +1 -1
  47. package/dist/replay/use-replay-storage.js +34 -5
  48. package/dist/replay/use-replay-storage.spec.d.ts +2 -0
  49. package/dist/replay/use-replay-storage.spec.d.ts.map +1 -0
  50. package/dist/replay/use-replay-storage.spec.js +74 -0
  51. package/dist/replay/use-replay.d.ts +2 -2
  52. package/dist/replay/use-replay.d.ts.map +1 -1
  53. package/dist/replay/use-replay.js +8 -20
  54. package/dist/replay/use-replay.spec.js +125 -101
  55. package/dist/session/use-session-storage.js +2 -2
  56. package/dist/session/use-session.js +2 -2
  57. package/dist/storage/index.d.ts +1 -0
  58. package/dist/storage/index.d.ts.map +1 -1
  59. package/dist/storage/index.js +1 -0
  60. package/dist/storage/use-storage.d.ts.map +1 -1
  61. package/dist/storage/use-storage.js +2 -2
  62. package/dist/use-execution-mode.d.ts +6 -1
  63. package/dist/use-execution-mode.d.ts.map +1 -1
  64. package/dist/use-execution-mode.js +16 -8
  65. package/dist/use-logger.js +4 -4
  66. package/dist/use-memo.d.ts +0 -10
  67. package/dist/use-memo.d.ts.map +1 -1
  68. package/dist/use-memo.js +0 -10
  69. package/dist/use-timestamp.js +2 -2
  70. package/dist/when-socket.d.ts +8 -0
  71. package/dist/when-socket.d.ts.map +1 -0
  72. package/dist/{use-socket.js → when-socket.js} +6 -5
  73. package/dist/with-memo.d.ts +5 -0
  74. package/dist/with-memo.d.ts.map +1 -0
  75. package/dist/{use.js → with-memo.js} +5 -5
  76. package/dist/with-memo.spec.d.ts +2 -0
  77. package/dist/with-memo.spec.d.ts.map +1 -0
  78. package/dist/{use.spec.js → with-memo.spec.js} +3 -3
  79. package/dist/{use-request.d.ts → with-request.d.ts} +5 -4
  80. package/dist/with-request.d.ts.map +1 -0
  81. package/dist/with-request.js +69 -0
  82. package/package.json +1 -1
  83. package/src/asset/asset.ts +6 -0
  84. package/src/cli/dev.ts +4 -20
  85. package/src/cli/internal/script.ts +49 -0
  86. package/src/cli/pull.ts +6 -66
  87. package/src/cli/replay.ts +4 -16
  88. package/src/cli/run.ts +4 -18
  89. package/src/index.ts +5 -14
  90. package/src/instrument/instrument.ts +6 -0
  91. package/src/make-test-module.ts +24 -4
  92. package/src/operators.ts +18 -0
  93. package/src/replay/index.ts +6 -4
  94. package/src/replay/replay-guard.ts +11 -0
  95. package/src/replay/replay.ts +13 -0
  96. package/src/replay/use-replay-breakpoint.ts +29 -0
  97. package/src/replay/use-replay-manager.ts +106 -0
  98. package/src/replay/use-replay-storage-buffer.ts +43 -0
  99. package/src/replay/use-replay-storage.spec.ts +85 -0
  100. package/src/replay/use-replay-storage.ts +26 -5
  101. package/src/replay/use-replay.spec.ts +10 -3
  102. package/src/replay/use-replay.ts +11 -17
  103. package/src/session/use-session-storage.ts +2 -2
  104. package/src/session/use-session.ts +2 -2
  105. package/src/storage/index.ts +1 -0
  106. package/src/storage/use-storage.ts +2 -2
  107. package/src/use-execution-mode.ts +16 -8
  108. package/src/use-logger.ts +4 -4
  109. package/src/use-memo.ts +0 -10
  110. package/src/use-timestamp.ts +2 -2
  111. package/src/{use-socket.ts → when-socket.ts} +6 -4
  112. package/src/{use.spec.ts → with-memo.spec.ts} +3 -3
  113. package/src/{use.ts → with-memo.ts} +4 -4
  114. package/src/with-request.ts +83 -0
  115. package/dist/as-readonly.d.ts +0 -3
  116. package/dist/as-readonly.d.ts.map +0 -1
  117. package/dist/as-readonly.js +0 -8
  118. package/dist/defined.d.ts +0 -3
  119. package/dist/defined.d.ts.map +0 -1
  120. package/dist/defined.js +0 -8
  121. package/dist/exclude.d.ts +0 -3
  122. package/dist/exclude.d.ts.map +0 -1
  123. package/dist/exclude.js +0 -8
  124. package/dist/not-found.d.ts +0 -2
  125. package/dist/not-found.d.ts.map +0 -1
  126. package/dist/not-found.js +0 -4
  127. package/dist/replay/use-replay-coordinator.d.ts +0 -10
  128. package/dist/replay/use-replay-coordinator.d.ts.map +0 -1
  129. package/dist/replay/use-replay-coordinator.js +0 -119
  130. package/dist/replay/use-replay-reader.d.ts +0 -7
  131. package/dist/replay/use-replay-reader.d.ts.map +0 -1
  132. package/dist/replay/use-replay-reader.js +0 -32
  133. package/dist/replay/use-replay-reader.spec.d.ts +0 -2
  134. package/dist/replay/use-replay-reader.spec.d.ts.map +0 -1
  135. package/dist/replay/use-replay-reader.spec.js +0 -58
  136. package/dist/replay/use-replay-writer.d.ts +0 -6
  137. package/dist/replay/use-replay-writer.d.ts.map +0 -1
  138. package/dist/replay/use-replay-writer.js +0 -14
  139. package/dist/replay/use-replay-writer.spec.d.ts +0 -2
  140. package/dist/replay/use-replay-writer.spec.d.ts.map +0 -1
  141. package/dist/replay/use-replay-writer.spec.js +0 -53
  142. package/dist/replay/with-replay.d.ts +0 -4
  143. package/dist/replay/with-replay.d.ts.map +0 -1
  144. package/dist/replay/with-replay.js +0 -8
  145. package/dist/strat.d.ts +0 -7
  146. package/dist/strat.d.ts.map +0 -1
  147. package/dist/strat.js +0 -7
  148. package/dist/use-lock.d.ts +0 -9
  149. package/dist/use-lock.d.ts.map +0 -1
  150. package/dist/use-lock.js +0 -40
  151. package/dist/use-request.d.ts.map +0 -1
  152. package/dist/use-request.js +0 -27
  153. package/dist/use-socket.d.ts +0 -6
  154. package/dist/use-socket.d.ts.map +0 -1
  155. package/dist/use-state.d.ts +0 -4
  156. package/dist/use-state.d.ts.map +0 -1
  157. package/dist/use-state.js +0 -24
  158. package/dist/use-state.spec.d.ts +0 -2
  159. package/dist/use-state.spec.d.ts.map +0 -1
  160. package/dist/use-state.spec.js +0 -36
  161. package/dist/use.d.ts +0 -5
  162. package/dist/use.d.ts.map +0 -1
  163. package/dist/use.spec.d.ts +0 -2
  164. package/dist/use.spec.d.ts.map +0 -1
  165. package/src/as-readonly.ts +0 -5
  166. package/src/defined.ts +0 -6
  167. package/src/exclude.ts +0 -9
  168. package/src/not-found.ts +0 -1
  169. package/src/replay/use-replay-coordinator.ts +0 -142
  170. package/src/replay/use-replay-reader.spec.ts +0 -64
  171. package/src/replay/use-replay-reader.ts +0 -23
  172. package/src/replay/use-replay-writer.spec.ts +0 -56
  173. package/src/replay/use-replay-writer.ts +0 -17
  174. package/src/replay/with-replay.ts +0 -10
  175. package/src/strat.ts +0 -7
  176. package/src/use-lock.ts +0 -52
  177. package/src/use-request.ts +0 -47
  178. package/src/use-state.spec.ts +0 -31
  179. package/src/use-state.ts +0 -30
@@ -0,0 +1,85 @@
1
+ import { makeTestModule, mockedFunc } from '@lib/make-test-module';
2
+ import { Query, QueryObject, Storage } from '@lib/storage';
3
+ import { useStorage } from '@lib/storage';
4
+
5
+ import { useReplayStorage } from './use-replay-storage';
6
+
7
+ jest.mock('@lib/storage', () => ({
8
+ ...jest.requireActual('@lib/storage'),
9
+ useStorage: jest.fn()
10
+ }));
11
+
12
+ describe(useReplayStorage.name, () => {
13
+ let fixtures: Awaited<ReturnType<typeof getFixtures>>;
14
+
15
+ beforeEach(async () => {
16
+ fixtures = await getFixtures();
17
+ });
18
+
19
+ describe('query', () => {
20
+ test('happy path', async () => {
21
+ await fixtures.given.stored(fixtures.sample);
22
+ const sample = await fixtures.when.queried({});
23
+
24
+ expect(sample).toEqual(fixtures.sample);
25
+ });
26
+ });
27
+
28
+ describe('save', () => {
29
+ test('happy path', async () => {
30
+ await fixtures.when.saved(fixtures.sample);
31
+ await fixtures.then.stored(fixtures.sample);
32
+ });
33
+ });
34
+ });
35
+
36
+ async function getFixtures() {
37
+ const { act } = await makeTestModule([]);
38
+
39
+ const dependencies = ['binance:btc-usdt', 'candle', 'h1'];
40
+ const save: Storage['save'] = jest.fn();
41
+ const query: jest.MockedFunction<Storage['query']> = jest.fn();
42
+
43
+ mockedFunc(useStorage).mockReturnValue({ save, query } as any);
44
+
45
+ return {
46
+ sample: [
47
+ { timestamp: 1, payload: { o: 1.1, h: 1.1, l: 1.1, c: 1.1 } },
48
+ { timestamp: 2, payload: { o: 1.1, h: 2.2, l: 1.1, c: 2.2 } },
49
+ { timestamp: 3, payload: { o: 1.1, h: 3.3, l: 1.1, c: 3.3 } }
50
+ ],
51
+
52
+ given: {
53
+ stored<T>(sample: { timestamp: number; payload: T }[]) {
54
+ return query.mockReturnValue(
55
+ Promise.resolve(
56
+ sample.map(it => ({
57
+ timestamp: it.timestamp,
58
+ payload: JSON.stringify(it.payload)
59
+ }))
60
+ )
61
+ );
62
+ }
63
+ },
64
+ when: {
65
+ saved<T>(sample: { timestamp: number; payload: T }[]) {
66
+ return act(() => useReplayStorage(dependencies).save(sample));
67
+ },
68
+ queried<T>(query: Query<QueryObject>) {
69
+ return act(() => useReplayStorage<T>(dependencies).query(query));
70
+ }
71
+ },
72
+
73
+ then: {
74
+ stored<T>(sample: { timestamp: number; payload: T }[]) {
75
+ expect(save).toHaveBeenCalledWith(
76
+ expect.anything(),
77
+ sample.map(it => ({
78
+ timestamp: it.timestamp,
79
+ payload: JSON.stringify(it.payload)
80
+ }))
81
+ );
82
+ }
83
+ }
84
+ };
85
+ }
@@ -1,8 +1,29 @@
1
- import { Storage, useStorage } from '@lib/storage';
1
+ import { Query, QueryObject, Storage, useStorage } from '@lib/storage';
2
+ import { dependency, useHash } from '@lib/use-hash';
2
3
 
3
- export const replaySerializableObject = (key: string) =>
4
- Storage.createObject(key, { timestamp: 'number', json: 'string' });
4
+ export function useReplayStorage<T>(dependencies: dependency[]) {
5
+ const storage = useStorage(['replay']);
6
+ const storageObjectKey = useHash(dependencies);
7
+ const storageObject = Storage.createObject(storageObjectKey, {
8
+ timestamp: 'number',
9
+ payload: 'string'
10
+ });
5
11
 
6
- export function useReplayStorage() {
7
- return useStorage(['replay']);
12
+ return {
13
+ async query(query: Query<QueryObject>) {
14
+ return (await storage.query(storageObject, query)).map(it => ({
15
+ timestamp: it.timestamp,
16
+ payload: JSON.parse(it.payload) as T
17
+ }));
18
+ },
19
+ save(objects: { timestamp: number; payload: T }[]) {
20
+ return storage.save(
21
+ storageObject,
22
+ objects.map(it => ({
23
+ timestamp: it.timestamp,
24
+ payload: JSON.stringify(it.payload)
25
+ }))
26
+ );
27
+ }
28
+ };
8
29
  }
@@ -1,15 +1,21 @@
1
+ import exp from 'constants';
1
2
  import { from, lastValueFrom, tap } from 'rxjs';
2
3
 
3
4
  import { makeTestModule } from '@lib/make-test-module';
4
- import { useReplayCoordinator } from '@lib/replay/use-replay-coordinator';
5
5
  import { replayExecutionMode } from '@lib/use-execution-mode';
6
6
  import { dependency } from '@lib/use-hash';
7
7
 
8
8
  import { between } from '..';
9
9
  import { useReplay } from './use-replay';
10
10
  import { replayOptions } from './use-replay-options';
11
- import { useReplayReader } from './use-replay-reader';
12
- import { useReplayWriter } from './use-replay-writer';
11
+
12
+ describe(useReplay.name, () => {
13
+ test('happy path', () => {
14
+ expect(true).toBe(true);
15
+ });
16
+ });
17
+
18
+ /*
13
19
 
14
20
  describe.skip(useReplayCoordinator.name, () => {
15
21
  let fixtures: Awaited<ReturnType<typeof getFixtures>>;
@@ -130,3 +136,4 @@ async function getFixtures() {
130
136
  }
131
137
  };
132
138
  }
139
+ */
@@ -1,34 +1,28 @@
1
- import { concatMap, map, Observable } from 'rxjs';
1
+ import { Observable, tap } from 'rxjs';
2
2
 
3
- import { useReplayCoordinator } from '@lib/replay/use-replay-coordinator';
4
3
  import { useExecutionMode } from '@lib/use-execution-mode';
5
4
  import { dependency } from '@lib/use-hash';
6
5
 
7
- import { useReplayWriter } from './use-replay-writer';
6
+ import { useReplayManager } from './use-replay-manager';
7
+ import { useReplayStorage } from './use-replay-storage';
8
8
 
9
- export const useReplay = <T>(
9
+ export function useReplay<T>(
10
10
  input: Observable<{ timestamp: number; payload: T }>,
11
11
  dependencies: dependency[]
12
- ) => {
12
+ ) {
13
13
  const { isReplay, recording } = useExecutionMode();
14
14
 
15
15
  if (isReplay) {
16
- const { subscribe } = useReplayCoordinator();
16
+ const { when } = useReplayManager();
17
17
 
18
- return subscribe(dependencies).pipe(
19
- map(it => it as unknown as { timestamp: number; payload: T })
20
- );
18
+ return when<T>(dependencies);
21
19
  }
22
20
 
23
21
  if (recording) {
24
- const writer = useReplayWriter(dependencies);
25
- return input.pipe(
26
- concatMap(async it => {
27
- await writer([it]);
28
- return it;
29
- })
30
- );
22
+ const { save } = useReplayStorage<T>(dependencies);
23
+
24
+ return input.pipe(tap(it => save([it])));
31
25
  }
32
26
 
33
27
  return input;
34
- };
28
+ }
@@ -1,8 +1,8 @@
1
1
  import { useSession } from '@lib/session';
2
2
  import { useStorage } from '@lib/storage';
3
- import { use } from '@lib/use';
3
+ import { withMemo } from '@lib/with-memo';
4
4
 
5
- export const useSessionStorage = use(() => {
5
+ export const useSessionStorage = withMemo(() => {
6
6
  const { id } = useSession();
7
7
 
8
8
  return useStorage(['session', id]);
@@ -1,5 +1,5 @@
1
- import { use } from '@lib/use';
1
+ import { withMemo } from '@lib/with-memo';
2
2
 
3
- export const useSession = use(() => ({
3
+ export const useSession = withMemo(() => ({
4
4
  id: 'ttt' //Date.now()
5
5
  }));
@@ -1,4 +1,5 @@
1
1
  export * from './storage';
2
+ export * from './use-cache';
2
3
  export * from './use-storage';
3
4
  export * from './use-storage-factory';
4
5
  export * from './in-memory';
@@ -1,9 +1,9 @@
1
- import { use } from '@lib/use';
2
1
  import { dependency, useHash } from '@lib/use-hash';
2
+ import { withMemo } from '@lib/with-memo';
3
3
 
4
4
  import { useStorageFactory } from './use-storage-factory';
5
5
 
6
- export const useStorage = use((dependencies: dependency[]) => {
6
+ export const useStorage = withMemo((dependencies: dependency[]) => {
7
7
  const key = useHash(dependencies);
8
8
  const factory = useStorageFactory();
9
9
 
@@ -3,28 +3,35 @@ import { useContext } from '@lib/module';
3
3
  const injectionToken = Symbol('execution-mode');
4
4
 
5
5
  type ExecutionMode = {
6
- mode: 'REPLAY' | 'PAPER' | 'LIVE';
6
+ mode: 'replay' | 'paper' | 'live' | 'idle';
7
7
  recording: boolean;
8
8
  };
9
9
 
10
10
  export function replayExecutionMode() {
11
11
  return {
12
12
  provide: injectionToken,
13
- useValue: { mode: 'REPLAY', recording: false } as ExecutionMode
13
+ useValue: { mode: 'replay', recording: false } as ExecutionMode
14
14
  };
15
15
  }
16
16
 
17
17
  export function paperExecutionMode(options: { recording: boolean }) {
18
18
  return {
19
19
  provide: injectionToken,
20
- useValue: { mode: 'PAPER', ...options } as ExecutionMode
20
+ useValue: { mode: 'paper', ...options } as ExecutionMode
21
21
  };
22
22
  }
23
23
 
24
24
  export function liveExecutionMode(options: { recording: boolean }) {
25
25
  return {
26
26
  provide: injectionToken,
27
- useValue: { mode: 'LIVE', ...options } as ExecutionMode
27
+ useValue: { mode: 'live', ...options } as ExecutionMode
28
+ };
29
+ }
30
+
31
+ export function idleExecutionMode() {
32
+ return {
33
+ provide: injectionToken,
34
+ useValue: { mode: 'idle', recording: false } as ExecutionMode
28
35
  };
29
36
  }
30
37
 
@@ -32,10 +39,11 @@ export const useExecutionMode = () => {
32
39
  const mode = useContext<ExecutionMode>(injectionToken);
33
40
 
34
41
  return {
35
- isReplay: mode.mode === 'REPLAY',
36
- isPaper: mode.mode === 'PAPER',
37
- isLive: mode.mode === 'LIVE',
38
- isSimulation: mode.mode !== 'LIVE',
42
+ isReplay: mode.mode === 'replay',
43
+ isPaper: mode.mode === 'paper',
44
+ isLive: mode.mode === 'live',
45
+ isIdle: mode.mode === 'idle',
46
+ isSimulation: mode.mode !== 'live',
39
47
  recording: mode.recording
40
48
  };
41
49
  };
package/src/use-logger.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import chalk from 'chalk';
2
2
 
3
- import { use } from './use';
4
3
  import { useTimestamp } from './use-timestamp';
4
+ import { withMemo } from './with-memo';
5
5
 
6
6
  const colorize = (content: string) => {
7
7
  let hash = 0x811c9dc5;
@@ -17,7 +17,7 @@ const colorize = (content: string) => {
17
17
  /**
18
18
  *
19
19
  */
20
- export const useLogger = use((context: string, tint?: string) => {
20
+ export const useLogger = withMemo((context: string, tint?: string) => {
21
21
  const prefix = () =>
22
22
  `${chalk.gray(new Date(useTimestamp()).toISOString())} ${chalk.hex(
23
23
  tint ?? colorize(context)
@@ -41,7 +41,7 @@ export const useLogger = use((context: string, tint?: string) => {
41
41
 
42
42
  error: (message: any, ...params: unknown[]) =>
43
43
  params?.length
44
- ? console.error(`${prefix()}: ${message}`, params)
45
- : console.error(`${prefix()}: ${message}`)
44
+ ? console.error(`${prefix()}: ${chalk.red(message)}`, params)
45
+ : console.error(`${prefix()}: ${chalk.red(message)}`)
46
46
  };
47
47
  });
package/src/use-memo.ts CHANGED
@@ -13,16 +13,6 @@ export function memo() {
13
13
  };
14
14
  }
15
15
 
16
- /**
17
- * @name useMemo
18
- * @description
19
- * A hook that caches the result of an expensive calculation, based on a set of dependencies.
20
- *
21
- * @template T The type of the value that is memoized.
22
- * @param {() => T} calculateValue A function that returns the value to memoize.
23
- * @param {dependency[]} dependencies An array of dependencies that determine when the value should be recalculated.
24
- * @returns {T} The memoized value.
25
- */
26
16
  export function useMemo<T>(calculateValue: () => T, dependencies: dependency[]) {
27
17
  const memory = useContext<Record<string, any>>(token);
28
18
  const hash = useHash(dependencies);
@@ -1,11 +1,11 @@
1
- import { useReplayCoordinator } from '@lib/replay/use-replay-coordinator';
1
+ import { useReplayManager } from '@lib/replay';
2
2
  import { useExecutionMode } from '@lib/use-execution-mode';
3
3
 
4
4
  export function useTimestamp() {
5
5
  const { isReplay } = useExecutionMode();
6
6
 
7
7
  if (isReplay) {
8
- return useReplayCoordinator().timestamp();
8
+ return useReplayManager().timestamp();
9
9
  }
10
10
 
11
11
  return Date.now();
@@ -4,10 +4,11 @@ import { WebSocket } from 'ws';
4
4
  import { useLogger } from './use-logger';
5
5
  import { useTimestamp } from './use-timestamp';
6
6
 
7
- export function useSocket(
8
- url: string
7
+ export function whenSocket(
8
+ url: string,
9
+ options: { pingInterval?: number } = { pingInterval: 5000 }
9
10
  ): [Observable<{ timestamp: number; payload: unknown }>, (message: unknown) => void] {
10
- const { debug } = useLogger('useSocket');
11
+ const { debug } = useLogger('whenSocket');
11
12
 
12
13
  const message = new Observable<{ timestamp: number; payload: unknown }>(stream => {
13
14
  const socket = new WebSocket(url);
@@ -18,6 +19,7 @@ export function useSocket(
18
19
  stream.next({ timestamp: useTimestamp(), payload: JSON.parse(it.data as string) });
19
20
  socket.onerror = it => {
20
21
  clearInterval(interval);
22
+ debug('errored', url);
21
23
  stream.error(it);
22
24
  };
23
25
  socket.onclose = () => {
@@ -37,7 +39,7 @@ export function useSocket(
37
39
  socket.terminate();
38
40
  clearInterval(interval);
39
41
  }
40
- }, 5000);
42
+ }, options.pingInterval);
41
43
 
42
44
  socket.on('pong', () => {
43
45
  isAlive = true;
@@ -1,9 +1,9 @@
1
1
  import { makeTestModule } from '@lib/make-test-module';
2
2
 
3
3
  import { instrumentOf, InstrumentSelector } from './instrument';
4
- import { use } from './use';
4
+ import { withMemo } from './with-memo';
5
5
 
6
- describe(use.name, () => {
6
+ describe(withMemo.name, () => {
7
7
  let fixtures: Awaited<ReturnType<typeof getFixtures>>;
8
8
 
9
9
  beforeEach(async () => {
@@ -37,7 +37,7 @@ describe(use.name, () => {
37
37
  async function getFixtures() {
38
38
  const { act } = await makeTestModule([]);
39
39
 
40
- const getValue = use((instrument: InstrumentSelector) => instrument.id);
40
+ const getValue = withMemo((instrument: InstrumentSelector) => instrument.id);
41
41
 
42
42
  return {
43
43
  act,
@@ -1,19 +1,19 @@
1
1
  import { isObservable, Observable, shareReplay } from 'rxjs';
2
2
  import { v4 } from 'uuid';
3
3
 
4
- import { asReadonly } from './as-readonly';
5
4
  import { throwWithContext } from './module';
5
+ import { asReadonly } from './operators';
6
6
  import { dependency } from './use-hash';
7
7
  import { useMemo } from './use-memo';
8
8
 
9
- export function use<T extends Array<dependency>, U>(
9
+ export function withMemo<T extends Array<dependency>, U>(
10
10
  fn: (...args: T) => U
11
11
  ): (...args: T) => U;
12
- export function use<T extends Array<dependency>, U>(
12
+ export function withMemo<T extends Array<dependency>, U>(
13
13
  fn: (...args: T) => Observable<U>
14
14
  ): (...args: T) => Observable<U>;
15
15
 
16
- export function use<T extends Array<dependency>, U>(
16
+ export function withMemo<T extends Array<dependency>, U>(
17
17
  fn: (...args: T) => U | Observable<U>
18
18
  ): (...args: T) => U | Observable<U> {
19
19
  throwWithContext();
@@ -0,0 +1,83 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { Observable } from 'rxjs';
3
+ import { request } from 'undici';
4
+
5
+ import { useLogger } from './use-logger';
6
+ import { useTimestamp } from './use-timestamp';
7
+
8
+ export type RequestMethod =
9
+ | 'GET'
10
+ | 'HEAD'
11
+ | 'POST'
12
+ | 'PUT'
13
+ | 'DELETE'
14
+ | 'CONNECT'
15
+ | 'OPTIONS'
16
+ | 'TRACE'
17
+ | 'PATCH';
18
+
19
+ export class RequestNetworkError extends Error {
20
+ constructor(readonly statusCode: number, readonly json: () => Promise<string>) {
21
+ super(`Request network error, received status code: ${statusCode}`);
22
+ }
23
+ }
24
+
25
+ export function withRequest({
26
+ method,
27
+ url,
28
+ headers,
29
+ body
30
+ }: {
31
+ method: RequestMethod;
32
+ url: string;
33
+ headers?: Record<string, any>;
34
+ body?: string;
35
+ }) {
36
+ const { error, debug } = useLogger(withRequest.name);
37
+
38
+ return new Observable<{ timestamp: number; payload: unknown }>(subscriber => {
39
+ const correlationId = randomUUID();
40
+
41
+ debug('requesting', { correlationId, method, url, headers, body });
42
+
43
+ request(url, { method, headers, body })
44
+ .then(async ({ statusCode, body }) => {
45
+ const json = await body.json();
46
+
47
+ debug('received', {
48
+ correlationId,
49
+ method,
50
+ url,
51
+ headers,
52
+ body: json,
53
+ statusCode
54
+ });
55
+
56
+ if (statusCode !== 200) {
57
+ error(`errored`, {
58
+ method,
59
+ url,
60
+ headers,
61
+ body,
62
+ statusCode
63
+ });
64
+
65
+ subscriber.error(new RequestNetworkError(statusCode, () => json));
66
+ } else {
67
+ subscriber.next({ timestamp: useTimestamp(), payload: json });
68
+ }
69
+ })
70
+ .catch((e: Error) => {
71
+ error(`errored`, {
72
+ method,
73
+ url,
74
+ headers,
75
+ body,
76
+ error: e
77
+ });
78
+
79
+ subscriber.error(error);
80
+ })
81
+ .finally(() => subscriber.complete());
82
+ });
83
+ }
@@ -1,3 +0,0 @@
1
- import { Observable } from 'rxjs';
2
- export declare function asReadonly<T>(): (input: Observable<T>) => Observable<Readonly<T>>;
3
- //# sourceMappingURL=as-readonly.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"as-readonly.d.ts","sourceRoot":"","sources":["../src/as-readonly.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,UAAU,EAAE,MAAM,MAAM,CAAC;AAEvC,wBAAgB,UAAU,CAAC,CAAC,aACX,WAAW,CAAC,CAAC,6BAC7B"}
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.asReadonly = void 0;
4
- const rxjs_1 = require("rxjs");
5
- function asReadonly() {
6
- return (input) => input.pipe((0, rxjs_1.map)(it => it));
7
- }
8
- exports.asReadonly = asReadonly;
package/dist/defined.d.ts DELETED
@@ -1,3 +0,0 @@
1
- import { Observable } from 'rxjs';
2
- export declare function defined<T>(): (observable: Observable<T | undefined | null>) => Observable<T | null | undefined>;
3
- //# sourceMappingURL=defined.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"defined.d.ts","sourceRoot":"","sources":["../src/defined.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,UAAU,EAAE,MAAM,MAAM,CAAC;AAE1C,wBAAgB,OAAO,CAAC,CAAC,kBACH,WAAW,CAAC,GAAG,SAAS,GAAG,IAAI,CAAC,sCAErD"}
package/dist/defined.js DELETED
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defined = void 0;
4
- const rxjs_1 = require("rxjs");
5
- function defined() {
6
- return (observable) => observable.pipe((0, rxjs_1.filter)(it => it !== undefined && it !== null));
7
- }
8
- exports.defined = defined;
package/dist/exclude.d.ts DELETED
@@ -1,3 +0,0 @@
1
- import { Observable } from 'rxjs';
2
- export declare function exclude<T, S extends symbol>(s: S): (observable: Observable<T | S>) => Observable<Exclude<T, S>>;
3
- //# sourceMappingURL=exclude.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"exclude.d.ts","sourceRoot":"","sources":["../src/exclude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,UAAU,EAAE,MAAM,MAAM,CAAC;AAE/C,wBAAgB,OAAO,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAAC,gBAC3B,WAAW,CAAC,GAAG,CAAC,CAAC,+BAKtC"}
package/dist/exclude.js DELETED
@@ -1,8 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.exclude = void 0;
4
- const rxjs_1 = require("rxjs");
5
- function exclude(s) {
6
- return (observable) => observable.pipe((0, rxjs_1.filter)(it => it !== s), (0, rxjs_1.map)(it => it));
7
- }
8
- exports.exclude = exclude;
@@ -1,2 +0,0 @@
1
- export declare const notFound: unique symbol;
2
- //# sourceMappingURL=not-found.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"not-found.d.ts","sourceRoot":"","sources":["../src/not-found.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,eAA0B,CAAC"}
package/dist/not-found.js DELETED
@@ -1,4 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.notFound = void 0;
4
- exports.notFound = Symbol.for('not-found');
@@ -1,10 +0,0 @@
1
- import { dependency } from '../use-hash';
2
- export declare function useReplayCoordinator(): {
3
- timestamp: () => number;
4
- stop: () => number;
5
- tryContinue: () => void;
6
- subscribe: (dependencies: dependency[]) => import("rxjs").Observable<{
7
- timestamp: number;
8
- }>;
9
- };
10
- //# sourceMappingURL=use-replay-coordinator.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"use-replay-coordinator.d.ts","sourceRoot":"","sources":["../../src/replay/use-replay-coordinator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAO3C,wBAAgB,oBAAoB;;;;8BAUC,UAAU,EAAE;mBAFW,MAAM;;EAsFjE"}