Repository navigation
Expand file tree
/
Copy pathactions.ts
More file actions
110 lines (89 loc) · 2.84 KB
/
Copy pathactions.ts
File metadata and controls
110 lines (89 loc) · 2.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import type { Dispatcher } from '../Dispatcher.js'
import type { MessageCreator, WorkerMessage } from '../types.js'
// --- Core Message Creators ---
const identityPayloadCreator = <P>(payload: P) => payload
export function createMessage<
P = unknown,
R = unknown,
Args extends unknown[] = [payload: P],
>(
type: string,
payloadCreator: (...args: Args) => P = identityPayloadCreator as unknown as (
...args: Args
) => P,
metaCreator?: (...args: Args) => WorkerMessage<P, R>['meta']
) {
const messageCreator: MessageCreator<P, R, Args> = (
...args: Args
): WorkerMessage<P, R> => {
const payload = payloadCreator(...args)
const message: WorkerMessage<P, R> = { type, payload }
if (metaCreator != null) {
const meta = metaCreator(...args)
if (meta != null) {
message.meta = meta
}
}
return message
}
messageCreator.toString = () => type
return messageCreator
}
/** @deprecated Use createMessage */
export const createAction = createMessage
// --- Bulk Creation Utilities ---
type PayloadCreator<Args extends unknown[] = unknown[], Result = unknown> = (
...args: Args
) => Result
interface MessageMap {
[key: string]: PayloadCreator | MessageMap
}
export function createMessages(
messageMap: MessageMap,
prefix = ''
): Record<string, unknown> {
const messages: Record<string, unknown> = {}
for (const [key, value] of Object.entries(messageMap)) {
const type = prefix.length > 0 ? `${prefix}/${key}` : key
if (typeof value === 'function') {
// It's a payload creator
messages[key] = createMessage(type, value)
} else if (typeof value === 'object' && value !== null) {
// Recursive definition
messages[key] = createMessages(value, type)
}
}
return messages
}
/** @deprecated Use createMessages */
export const createActions = createMessages
// --- Binding Utilities ---
export function bindMessageCreators(
messageCreators: Record<string, PayloadCreator>,
dispatcher: Dispatcher
) {
const bound: Record<string, PayloadCreator> = {}
for (const [key, creator] of Object.entries(messageCreators)) {
bound[key] = async (...args: unknown[]) => {
const message = creator(...args)
if (!isWorkerMessage(message)) {
throw new Error('Message creator must return a WorkerMessage')
}
// Default to call (RPC) for bound messages as it covers both use cases safely
return await dispatcher.call(message)
}
}
return bound
}
/** @deprecated Use bindMessageCreators */
export const bindActionCreators = bindMessageCreators
export function isWorkerMessage(message: unknown): message is WorkerMessage {
return (
typeof message === 'object' &&
message !== null &&
'type' in message &&
typeof message.type === 'string'
)
}
/** @deprecated Use isWorkerMessage */
export const isWorkerAction = isWorkerMessage