datool 0.0.2 → 0.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.
- package/package.json +1 -1
- package/src/client/App.tsx +24 -7
- package/src/client/stream-state.ts +20 -0
- package/src/node/server.ts +17 -2
- package/src/shared/types.ts +4 -0
package/package.json
CHANGED
package/src/client/App.tsx
CHANGED
|
@@ -25,6 +25,7 @@ import type {
|
|
|
25
25
|
DatoolClientConfig,
|
|
26
26
|
DatoolClientStream,
|
|
27
27
|
DatoolColumn,
|
|
28
|
+
DatoolSseEndEvent,
|
|
28
29
|
DatoolRowEvent,
|
|
29
30
|
DatoolSseErrorEvent,
|
|
30
31
|
} from "../shared/types"
|
|
@@ -45,6 +46,7 @@ import {
|
|
|
45
46
|
writeDatoolUrlState,
|
|
46
47
|
} from "@/lib/datool-url-state"
|
|
47
48
|
import { LOG_VIEWER_ICONS } from "@/lib/datool-icons"
|
|
49
|
+
import { upsertViewerRow } from "./stream-state"
|
|
48
50
|
|
|
49
51
|
type ViewerRow = Record<string, unknown> & {
|
|
50
52
|
__datoolRowId: string
|
|
@@ -242,6 +244,10 @@ function parseErrorEvent(event: MessageEvent<string>) {
|
|
|
242
244
|
return JSON.parse(event.data) as DatoolSseErrorEvent
|
|
243
245
|
}
|
|
244
246
|
|
|
247
|
+
function parseEndEvent(event: MessageEvent<string>) {
|
|
248
|
+
return JSON.parse(event.data) as DatoolSseEndEvent
|
|
249
|
+
}
|
|
250
|
+
|
|
245
251
|
function stringifyRowActionValue(value: unknown) {
|
|
246
252
|
if (value === null || value === undefined) {
|
|
247
253
|
return ""
|
|
@@ -773,13 +779,12 @@ export default function App() {
|
|
|
773
779
|
const handleRow = (event: MessageEvent<string>) => {
|
|
774
780
|
const payload = parseRowEvent(event)
|
|
775
781
|
|
|
776
|
-
setRows((currentRows) =>
|
|
777
|
-
|
|
778
|
-
{
|
|
782
|
+
setRows((currentRows) =>
|
|
783
|
+
upsertViewerRow(currentRows, {
|
|
779
784
|
...payload.row,
|
|
780
785
|
__datoolRowId: payload.id,
|
|
781
|
-
}
|
|
782
|
-
|
|
786
|
+
})
|
|
787
|
+
)
|
|
783
788
|
}
|
|
784
789
|
|
|
785
790
|
const handleRuntimeError = (event: MessageEvent<string>) => {
|
|
@@ -788,6 +793,13 @@ export default function App() {
|
|
|
788
793
|
setErrorMessage(payload.message)
|
|
789
794
|
}
|
|
790
795
|
|
|
796
|
+
const handleEnd = (event: MessageEvent<string>) => {
|
|
797
|
+
parseEndEvent(event)
|
|
798
|
+
eventSource.close()
|
|
799
|
+
eventSourceRef.current = null
|
|
800
|
+
setIsConnected(false)
|
|
801
|
+
}
|
|
802
|
+
|
|
791
803
|
eventSource.onopen = () => {
|
|
792
804
|
setIsConnected(true)
|
|
793
805
|
}
|
|
@@ -797,14 +809,19 @@ export default function App() {
|
|
|
797
809
|
}
|
|
798
810
|
|
|
799
811
|
eventSource.addEventListener("row", handleRow as EventListener)
|
|
800
|
-
eventSource.addEventListener(
|
|
812
|
+
eventSource.addEventListener(
|
|
813
|
+
"runtime-error",
|
|
814
|
+
handleRuntimeError as EventListener
|
|
815
|
+
)
|
|
816
|
+
eventSource.addEventListener("end", handleEnd as EventListener)
|
|
801
817
|
|
|
802
818
|
return () => {
|
|
803
819
|
eventSource.removeEventListener("row", handleRow as EventListener)
|
|
804
820
|
eventSource.removeEventListener(
|
|
805
|
-
"error",
|
|
821
|
+
"runtime-error",
|
|
806
822
|
handleRuntimeError as EventListener
|
|
807
823
|
)
|
|
824
|
+
eventSource.removeEventListener("end", handleEnd as EventListener)
|
|
808
825
|
eventSource.close()
|
|
809
826
|
setIsConnected(false)
|
|
810
827
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type StreamViewerRow = Record<string, unknown> & {
|
|
2
|
+
__datoolRowId: string
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function upsertViewerRow<T extends StreamViewerRow>(
|
|
6
|
+
currentRows: T[],
|
|
7
|
+
nextRow: T
|
|
8
|
+
) {
|
|
9
|
+
const existingIndex = currentRows.findIndex(
|
|
10
|
+
(row) => row.__datoolRowId === nextRow.__datoolRowId
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
if (existingIndex < 0) {
|
|
14
|
+
return [...currentRows, nextRow]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return currentRows.map((row, index) =>
|
|
18
|
+
index === existingIndex ? nextRow : row
|
|
19
|
+
)
|
|
20
|
+
}
|
package/src/node/server.ts
CHANGED
|
@@ -10,6 +10,7 @@ import type {
|
|
|
10
10
|
DatoolActionResolveResult,
|
|
11
11
|
DatoolActionResponse,
|
|
12
12
|
DatoolConfig,
|
|
13
|
+
DatoolSseEndEvent,
|
|
13
14
|
DatoolSseErrorEvent,
|
|
14
15
|
} from "../shared/types"
|
|
15
16
|
|
|
@@ -74,6 +75,12 @@ function toErrorPayload(error: unknown): DatoolSseErrorEvent {
|
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
|
|
78
|
+
function toEndPayload(reason: DatoolSseEndEvent["reason"]): DatoolSseEndEvent {
|
|
79
|
+
return {
|
|
80
|
+
reason,
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
77
84
|
function encodeSseEvent(event: string, data: unknown) {
|
|
78
85
|
return `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`
|
|
79
86
|
}
|
|
@@ -279,15 +286,23 @@ function createSseResponse(
|
|
|
279
286
|
abortController.signal,
|
|
280
287
|
{
|
|
281
288
|
async onError(error) {
|
|
282
|
-
send("error", toErrorPayload(error))
|
|
289
|
+
send("runtime-error", toErrorPayload(error))
|
|
283
290
|
},
|
|
284
291
|
async onRow(payload) {
|
|
285
292
|
send("row", payload)
|
|
286
293
|
},
|
|
287
294
|
}
|
|
288
295
|
)
|
|
296
|
+
.then(() => {
|
|
297
|
+
if (!abortController.signal.aborted) {
|
|
298
|
+
send("end", toEndPayload("completed"))
|
|
299
|
+
}
|
|
300
|
+
})
|
|
289
301
|
.catch((error) => {
|
|
290
|
-
|
|
302
|
+
if (!abortController.signal.aborted) {
|
|
303
|
+
send("runtime-error", toErrorPayload(error))
|
|
304
|
+
send("end", toEndPayload("error"))
|
|
305
|
+
}
|
|
291
306
|
})
|
|
292
307
|
.finally(() => {
|
|
293
308
|
clearInterval(heartbeat)
|
package/src/shared/types.ts
CHANGED