@tiga-ipc/mmap 0.2.0 → 0.3.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/README.md +15 -15
- package/index.d.ts +9 -9
- package/package.json +1 -1
- package/runtime/server.js +36 -39
- package/runtime/workers/notification-listener.js +1 -1
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ Current package scope:
|
|
|
21
21
|
|
|
22
22
|
- Windows only
|
|
23
23
|
- File-backed mapping usage
|
|
24
|
-
- `
|
|
24
|
+
- `ipcDirectory` must be passed explicitly by the caller
|
|
25
25
|
|
|
26
26
|
## Usage
|
|
27
27
|
|
|
@@ -34,10 +34,10 @@ const {
|
|
|
34
34
|
} = require('@tiga-ipc/mmap');
|
|
35
35
|
|
|
36
36
|
async function main() {
|
|
37
|
-
const
|
|
37
|
+
const ipcDirectory = 'C:\\temp\\tiga-ipc';
|
|
38
38
|
const server = startTigaServer({
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
channelName: 'sample',
|
|
40
|
+
ipcDirectory,
|
|
41
41
|
onInvoke(method, data) {
|
|
42
42
|
if (method === 'echo') {
|
|
43
43
|
return `reply:${data}`;
|
|
@@ -54,7 +54,7 @@ async function main() {
|
|
|
54
54
|
'echo',
|
|
55
55
|
'hello from node',
|
|
56
56
|
{
|
|
57
|
-
|
|
57
|
+
ipcDirectory,
|
|
58
58
|
timeoutMs: 3000,
|
|
59
59
|
},
|
|
60
60
|
);
|
|
@@ -62,12 +62,12 @@ async function main() {
|
|
|
62
62
|
console.log(reply);
|
|
63
63
|
|
|
64
64
|
tigaWrite('sample.events', 'event payload', {
|
|
65
|
-
|
|
65
|
+
ipcDirectory,
|
|
66
66
|
mediaType: 'text/plain',
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
const result = tigaRead('sample.events', {
|
|
70
|
-
|
|
70
|
+
ipcDirectory,
|
|
71
71
|
lastId: 0,
|
|
72
72
|
});
|
|
73
73
|
|
|
@@ -89,7 +89,7 @@ main().catch((error) => {
|
|
|
89
89
|
|
|
90
90
|
- `name: string`
|
|
91
91
|
- `message: Buffer | string`
|
|
92
|
-
- `options?.
|
|
92
|
+
- `options?.ipcDirectory: string`
|
|
93
93
|
- `options?.mediaType?: string`
|
|
94
94
|
|
|
95
95
|
Returns a short write result string from the native addon.
|
|
@@ -97,7 +97,7 @@ Returns a short write result string from the native addon.
|
|
|
97
97
|
### `tigaRead(name, options?)`
|
|
98
98
|
|
|
99
99
|
- `name: string`
|
|
100
|
-
- `options?.
|
|
100
|
+
- `options?.ipcDirectory: string`
|
|
101
101
|
- `options?.lastId?: number`
|
|
102
102
|
|
|
103
103
|
Returns:
|
|
@@ -119,15 +119,15 @@ interface TigaReadResult {
|
|
|
119
119
|
- `responseName: string`
|
|
120
120
|
- `method: string`
|
|
121
121
|
- `data: string`
|
|
122
|
-
- `options?.
|
|
122
|
+
- `options?.ipcDirectory: string`
|
|
123
123
|
- `options?.timeoutMs?: number`
|
|
124
124
|
|
|
125
125
|
Returns the response payload string.
|
|
126
126
|
|
|
127
127
|
### `startTigaServer(options)` / `createTigaServer(options)`
|
|
128
128
|
|
|
129
|
-
- `options.
|
|
130
|
-
- `options.
|
|
129
|
+
- `options.channelName: string`
|
|
130
|
+
- `options.ipcDirectory: string`
|
|
131
131
|
- `options.discoveryIntervalMs?: number`
|
|
132
132
|
- `options.waitTimeoutMs?: number`
|
|
133
133
|
- `options.onInvoke(method, data, context): unknown | Promise<unknown>`
|
|
@@ -139,11 +139,11 @@ Returns a `TigaServer` instance. `startTigaServer(...)` starts it immediately. `
|
|
|
139
139
|
|
|
140
140
|
```ts
|
|
141
141
|
interface TigaServerContext {
|
|
142
|
-
|
|
142
|
+
channelName: string;
|
|
143
143
|
clientId: string;
|
|
144
144
|
requestName: string;
|
|
145
145
|
responseName: string;
|
|
146
|
-
|
|
146
|
+
ipcDirectory: string;
|
|
147
147
|
requestId: string;
|
|
148
148
|
entryId: number;
|
|
149
149
|
mediaType?: string | null;
|
|
@@ -152,7 +152,7 @@ interface TigaServerContext {
|
|
|
152
152
|
|
|
153
153
|
The server helper keeps transport concerns inside the package:
|
|
154
154
|
|
|
155
|
-
- discovers per-client request channels under the configured `
|
|
155
|
+
- discovers per-client request channels under the configured `ipcDirectory`
|
|
156
156
|
- registers request listeners using the native notification mechanism
|
|
157
157
|
- decodes invoke payloads and writes response payloads back to the matching response channel
|
|
158
158
|
- surfaces business logic as a single `onInvoke(...)` callback
|
package/index.d.ts
CHANGED
|
@@ -14,19 +14,19 @@ export interface TigaEntry {
|
|
|
14
14
|
mediaType?: string
|
|
15
15
|
}
|
|
16
16
|
export interface TigaChannelOptions {
|
|
17
|
-
|
|
17
|
+
ipcDirectory?: string
|
|
18
18
|
}
|
|
19
19
|
export interface TigaWriteOptions {
|
|
20
20
|
mediaType?: string
|
|
21
|
-
|
|
21
|
+
ipcDirectory?: string
|
|
22
22
|
}
|
|
23
23
|
export interface TigaReadOptions {
|
|
24
24
|
lastId?: number
|
|
25
|
-
|
|
25
|
+
ipcDirectory?: string
|
|
26
26
|
}
|
|
27
27
|
export interface TigaInvokeOptions {
|
|
28
28
|
timeoutMs?: number
|
|
29
|
-
|
|
29
|
+
ipcDirectory?: string
|
|
30
30
|
}
|
|
31
31
|
export declare function tigaWrite(name: string, message: Buffer | string, options?: TigaWriteOptions | undefined | null): string
|
|
32
32
|
export declare function tigaRead(name: string, options?: TigaReadOptions | undefined | null): TigaReadResult
|
|
@@ -38,17 +38,17 @@ export declare class TigaNotificationListener {
|
|
|
38
38
|
get closed(): boolean
|
|
39
39
|
}
|
|
40
40
|
export interface TigaServerContext {
|
|
41
|
-
|
|
41
|
+
channelName: string
|
|
42
42
|
clientId: string
|
|
43
43
|
requestName: string
|
|
44
44
|
responseName: string
|
|
45
|
-
|
|
45
|
+
ipcDirectory: string
|
|
46
46
|
requestId: string
|
|
47
47
|
entryId: number
|
|
48
48
|
mediaType?: string | null
|
|
49
49
|
}
|
|
50
50
|
export interface TigaServerOptions extends TigaChannelOptions {
|
|
51
|
-
|
|
51
|
+
channelName: string
|
|
52
52
|
discoveryIntervalMs?: number
|
|
53
53
|
waitTimeoutMs?: number
|
|
54
54
|
onInvoke(method: string, data: unknown, context: TigaServerContext): unknown | Promise<unknown>
|
|
@@ -56,8 +56,8 @@ export interface TigaServerOptions extends TigaChannelOptions {
|
|
|
56
56
|
}
|
|
57
57
|
export declare class TigaServer {
|
|
58
58
|
constructor(options: TigaServerOptions)
|
|
59
|
-
readonly
|
|
60
|
-
readonly
|
|
59
|
+
readonly channelName: string
|
|
60
|
+
readonly ipcDirectory: string
|
|
61
61
|
readonly closed: boolean
|
|
62
62
|
readonly started: boolean
|
|
63
63
|
start(): TigaServer
|
package/package.json
CHANGED
package/runtime/server.js
CHANGED
|
@@ -26,17 +26,17 @@ const ensureString = (value, label) => {
|
|
|
26
26
|
return value.trim();
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
const getStatePath = (
|
|
30
|
-
path.join(
|
|
29
|
+
const getStatePath = (ipcDirectory, name) =>
|
|
30
|
+
path.join(ipcDirectory, `${FILE_PREFIX}${name}${STATE_SUFFIX}`);
|
|
31
31
|
|
|
32
|
-
const hasSingleChannel = (
|
|
33
|
-
fs.existsSync(getStatePath(
|
|
32
|
+
const hasSingleChannel = (channelName, ipcDirectory) =>
|
|
33
|
+
fs.existsSync(getStatePath(ipcDirectory, channelName));
|
|
34
34
|
|
|
35
|
-
const listClientIds = (
|
|
35
|
+
const listClientIds = (channelName, ipcDirectory) => {
|
|
36
36
|
try {
|
|
37
|
-
const prefix = `${FILE_PREFIX}${
|
|
37
|
+
const prefix = `${FILE_PREFIX}${channelName}.req.`;
|
|
38
38
|
return fs
|
|
39
|
-
.readdirSync(
|
|
39
|
+
.readdirSync(ipcDirectory)
|
|
40
40
|
.filter((fileName) => fileName.startsWith(prefix))
|
|
41
41
|
.filter((fileName) => fileName.endsWith(STATE_SUFFIX))
|
|
42
42
|
.map((fileName) =>
|
|
@@ -48,29 +48,26 @@ const listClientIds = (baseName, mappingDirectory) => {
|
|
|
48
48
|
}
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
const toClientState = (clientId,
|
|
51
|
+
const toClientState = (clientId, channelName) =>
|
|
52
52
|
clientId === SINGLE_CLIENT_ID
|
|
53
53
|
? {
|
|
54
54
|
key: SINGLE_CLIENT_ID,
|
|
55
55
|
clientId,
|
|
56
|
-
requestName:
|
|
57
|
-
responseName:
|
|
56
|
+
requestName: channelName,
|
|
57
|
+
responseName: channelName,
|
|
58
58
|
}
|
|
59
59
|
: {
|
|
60
60
|
key: clientId,
|
|
61
61
|
clientId,
|
|
62
|
-
requestName: `${
|
|
63
|
-
responseName: `${
|
|
62
|
+
requestName: `${channelName}.req.${clientId}`,
|
|
63
|
+
responseName: `${channelName}.resp.${clientId}`,
|
|
64
64
|
};
|
|
65
65
|
|
|
66
66
|
class TigaServer {
|
|
67
67
|
constructor(options) {
|
|
68
68
|
const resolved = options || {};
|
|
69
|
-
this.
|
|
70
|
-
this.
|
|
71
|
-
resolved.mappingDirectory,
|
|
72
|
-
'mappingDirectory',
|
|
73
|
-
);
|
|
69
|
+
this.channelName = ensureString(resolved.channelName, 'channelName');
|
|
70
|
+
this.ipcDirectory = ensureString(resolved.ipcDirectory, 'ipcDirectory');
|
|
74
71
|
if (typeof resolved.onInvoke !== 'function') {
|
|
75
72
|
throw new Error('onInvoke must be a function');
|
|
76
73
|
}
|
|
@@ -98,23 +95,23 @@ class TigaServer {
|
|
|
98
95
|
return this;
|
|
99
96
|
}
|
|
100
97
|
|
|
101
|
-
fs.mkdirSync(this.
|
|
98
|
+
fs.mkdirSync(this.ipcDirectory, { recursive: true });
|
|
102
99
|
this.started = true;
|
|
103
100
|
this.closed = false;
|
|
104
101
|
this.discoveryTimer = setInterval(() => {
|
|
105
102
|
this.discover().catch((error) => {
|
|
106
103
|
this.reportError(error, {
|
|
107
104
|
stage: 'discover',
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
channelName: this.channelName,
|
|
106
|
+
ipcDirectory: this.ipcDirectory,
|
|
110
107
|
});
|
|
111
108
|
});
|
|
112
109
|
}, this.discoveryIntervalMs);
|
|
113
110
|
this.discover().catch((error) => {
|
|
114
111
|
this.reportError(error, {
|
|
115
112
|
stage: 'discover',
|
|
116
|
-
|
|
117
|
-
|
|
113
|
+
channelName: this.channelName,
|
|
114
|
+
ipcDirectory: this.ipcDirectory,
|
|
118
115
|
});
|
|
119
116
|
});
|
|
120
117
|
|
|
@@ -143,18 +140,18 @@ class TigaServer {
|
|
|
143
140
|
return;
|
|
144
141
|
}
|
|
145
142
|
|
|
146
|
-
const nextClients = listClientIds(this.
|
|
143
|
+
const nextClients = listClientIds(this.channelName, this.ipcDirectory);
|
|
147
144
|
nextClients.forEach((clientId) => {
|
|
148
145
|
if (!this.clients.has(clientId)) {
|
|
149
|
-
this.registerClient(toClientState(clientId, this.
|
|
146
|
+
this.registerClient(toClientState(clientId, this.channelName));
|
|
150
147
|
}
|
|
151
148
|
});
|
|
152
149
|
|
|
153
150
|
if (
|
|
154
151
|
!this.clients.has(SINGLE_CLIENT_ID) &&
|
|
155
|
-
hasSingleChannel(this.
|
|
152
|
+
hasSingleChannel(this.channelName, this.ipcDirectory)
|
|
156
153
|
) {
|
|
157
|
-
this.registerClient(toClientState(SINGLE_CLIENT_ID, this.
|
|
154
|
+
this.registerClient(toClientState(SINGLE_CLIENT_ID, this.channelName));
|
|
158
155
|
}
|
|
159
156
|
}
|
|
160
157
|
|
|
@@ -184,7 +181,7 @@ class TigaServer {
|
|
|
184
181
|
{
|
|
185
182
|
workerData: {
|
|
186
183
|
name: client.requestName,
|
|
187
|
-
|
|
184
|
+
ipcDirectory: this.ipcDirectory,
|
|
188
185
|
waitTimeoutMs: this.waitTimeoutMs,
|
|
189
186
|
},
|
|
190
187
|
},
|
|
@@ -211,8 +208,8 @@ class TigaServer {
|
|
|
211
208
|
clientId: client.clientId,
|
|
212
209
|
requestName: client.requestName,
|
|
213
210
|
responseName: client.responseName,
|
|
214
|
-
|
|
215
|
-
|
|
211
|
+
channelName: this.channelName,
|
|
212
|
+
ipcDirectory: this.ipcDirectory,
|
|
216
213
|
});
|
|
217
214
|
}
|
|
218
215
|
});
|
|
@@ -223,8 +220,8 @@ class TigaServer {
|
|
|
223
220
|
clientId: client.clientId,
|
|
224
221
|
requestName: client.requestName,
|
|
225
222
|
responseName: client.responseName,
|
|
226
|
-
|
|
227
|
-
|
|
223
|
+
channelName: this.channelName,
|
|
224
|
+
ipcDirectory: this.ipcDirectory,
|
|
228
225
|
});
|
|
229
226
|
});
|
|
230
227
|
|
|
@@ -283,7 +280,7 @@ class TigaServer {
|
|
|
283
280
|
try {
|
|
284
281
|
result = binding.tigaRead(client.requestName, {
|
|
285
282
|
lastId: client.lastId,
|
|
286
|
-
|
|
283
|
+
ipcDirectory: this.ipcDirectory,
|
|
287
284
|
});
|
|
288
285
|
} catch (error) {
|
|
289
286
|
this.reportError(error, {
|
|
@@ -291,8 +288,8 @@ class TigaServer {
|
|
|
291
288
|
clientId: client.clientId,
|
|
292
289
|
requestName: client.requestName,
|
|
293
290
|
responseName: client.responseName,
|
|
294
|
-
|
|
295
|
-
|
|
291
|
+
channelName: this.channelName,
|
|
292
|
+
ipcDirectory: this.ipcDirectory,
|
|
296
293
|
});
|
|
297
294
|
return;
|
|
298
295
|
}
|
|
@@ -322,11 +319,11 @@ class TigaServer {
|
|
|
322
319
|
}
|
|
323
320
|
|
|
324
321
|
const context = {
|
|
325
|
-
|
|
322
|
+
channelName: this.channelName,
|
|
326
323
|
clientId: client.clientId,
|
|
327
324
|
requestName: client.requestName,
|
|
328
325
|
responseName: client.responseName,
|
|
329
|
-
|
|
326
|
+
ipcDirectory: this.ipcDirectory,
|
|
330
327
|
requestId: invoke.id,
|
|
331
328
|
entryId: entry.id,
|
|
332
329
|
mediaType: entry.mediaType || null,
|
|
@@ -362,7 +359,7 @@ class TigaServer {
|
|
|
362
359
|
try {
|
|
363
360
|
binding.tigaWrite(client.responseName, payload, {
|
|
364
361
|
mediaType: TIGA_MEDIA_TYPE_MSGPACK,
|
|
365
|
-
|
|
362
|
+
ipcDirectory: this.ipcDirectory,
|
|
366
363
|
});
|
|
367
364
|
} catch (error) {
|
|
368
365
|
this.reportError(error, {
|
|
@@ -370,8 +367,8 @@ class TigaServer {
|
|
|
370
367
|
clientId: client.clientId,
|
|
371
368
|
requestName: client.requestName,
|
|
372
369
|
responseName: client.responseName,
|
|
373
|
-
|
|
374
|
-
|
|
370
|
+
channelName: this.channelName,
|
|
371
|
+
ipcDirectory: this.ipcDirectory,
|
|
375
372
|
});
|
|
376
373
|
}
|
|
377
374
|
}
|