@effect-opcua/client 0.1.0-alpha.1
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/LICENSE +201 -0
- package/README.md +367 -0
- package/dist/Opcua.d.mts +13 -0
- package/dist/Opcua.d.mts.map +1 -0
- package/dist/Opcua.mjs +23 -0
- package/dist/Opcua.mjs.map +1 -0
- package/dist/OpcuaClient.d.mts +27 -0
- package/dist/OpcuaClient.d.mts.map +1 -0
- package/dist/OpcuaClient.mjs +20 -0
- package/dist/OpcuaClient.mjs.map +1 -0
- package/dist/OpcuaError.d.mts +249 -0
- package/dist/OpcuaError.d.mts.map +1 -0
- package/dist/OpcuaError.mjs +97 -0
- package/dist/OpcuaError.mjs.map +1 -0
- package/dist/OpcuaMethod.d.mts +158 -0
- package/dist/OpcuaMethod.d.mts.map +1 -0
- package/dist/OpcuaMethod.mjs +31 -0
- package/dist/OpcuaMethod.mjs.map +1 -0
- package/dist/OpcuaSession.d.mts +247 -0
- package/dist/OpcuaSession.d.mts.map +1 -0
- package/dist/OpcuaSession.mjs +50 -0
- package/dist/OpcuaSession.mjs.map +1 -0
- package/dist/OpcuaSubscription.d.mts +148 -0
- package/dist/OpcuaSubscription.d.mts.map +1 -0
- package/dist/OpcuaSubscription.mjs +45 -0
- package/dist/OpcuaSubscription.mjs.map +1 -0
- package/dist/OpcuaVariable.d.mts +179 -0
- package/dist/OpcuaVariable.d.mts.map +1 -0
- package/dist/OpcuaVariable.mjs +15 -0
- package/dist/OpcuaVariable.mjs.map +1 -0
- package/dist/_virtual/rolldown_runtime.mjs +18 -0
- package/dist/index.d.mts +8 -0
- package/dist/index.mjs +7 -0
- package/dist/internal/batch/chunk.d.mts +11 -0
- package/dist/internal/batch/chunk.d.mts.map +1 -0
- package/dist/internal/batch/chunk.mjs +23 -0
- package/dist/internal/batch/chunk.mjs.map +1 -0
- package/dist/internal/batch/keyed.d.mts +50 -0
- package/dist/internal/batch/keyed.d.mts.map +1 -0
- package/dist/internal/batch/keyed.mjs +112 -0
- package/dist/internal/batch/keyed.mjs.map +1 -0
- package/dist/internal/batch/operations.d.mts +25 -0
- package/dist/internal/batch/operations.d.mts.map +1 -0
- package/dist/internal/batch/operations.mjs +213 -0
- package/dist/internal/batch/operations.mjs.map +1 -0
- package/dist/internal/browse/operations.d.mts +15 -0
- package/dist/internal/browse/operations.d.mts.map +1 -0
- package/dist/internal/browse/operations.mjs +72 -0
- package/dist/internal/browse/operations.mjs.map +1 -0
- package/dist/internal/client/make.d.mts +16 -0
- package/dist/internal/client/make.d.mts.map +1 -0
- package/dist/internal/client/make.mjs +76 -0
- package/dist/internal/client/make.mjs.map +1 -0
- package/dist/internal/common/collections.d.mts +5 -0
- package/dist/internal/common/collections.d.mts.map +1 -0
- package/dist/internal/common/collections.mjs +10 -0
- package/dist/internal/common/collections.mjs.map +1 -0
- package/dist/internal/common/constants.d.mts +18 -0
- package/dist/internal/common/constants.d.mts.map +1 -0
- package/dist/internal/common/constants.mjs +19 -0
- package/dist/internal/common/constants.mjs.map +1 -0
- package/dist/internal/common/node-id.d.mts +2 -0
- package/dist/internal/common/node-id.mjs +1 -0
- package/dist/internal/common/options.d.mts +15 -0
- package/dist/internal/common/options.d.mts.map +1 -0
- package/dist/internal/common/options.mjs +22 -0
- package/dist/internal/common/options.mjs.map +1 -0
- package/dist/internal/common/predicates.d.mts +8 -0
- package/dist/internal/common/predicates.d.mts.map +1 -0
- package/dist/internal/common/predicates.mjs +13 -0
- package/dist/internal/common/predicates.mjs.map +1 -0
- package/dist/internal/data-types/enum.d.mts +2 -0
- package/dist/internal/data-types/enum.mjs +3 -0
- package/dist/internal/data-types/manager.d.mts +2 -0
- package/dist/internal/data-types/manager.mjs +3 -0
- package/dist/internal/data-types/model.d.mts +2 -0
- package/dist/internal/data-types/model.mjs +1 -0
- package/dist/internal/data-types/read.d.mts +14 -0
- package/dist/internal/data-types/read.d.mts.map +1 -0
- package/dist/internal/data-types/read.mjs +291 -0
- package/dist/internal/data-types/read.mjs.map +1 -0
- package/dist/internal/data-types/structure.d.mts +2 -0
- package/dist/internal/data-types/structure.mjs +3 -0
- package/dist/internal/events/model.d.mts +72 -0
- package/dist/internal/events/model.d.mts.map +1 -0
- package/dist/internal/events/model.mjs +1 -0
- package/dist/internal/events/wire.d.mts +37 -0
- package/dist/internal/events/wire.d.mts.map +1 -0
- package/dist/internal/events/wire.mjs +127 -0
- package/dist/internal/events/wire.mjs.map +1 -0
- package/dist/internal/metadata/arguments.d.mts +2 -0
- package/dist/internal/metadata/arguments.mjs +3 -0
- package/dist/internal/metadata/methods.d.mts +2 -0
- package/dist/internal/metadata/methods.mjs +3 -0
- package/dist/internal/metadata/service.d.mts +23 -0
- package/dist/internal/metadata/service.d.mts.map +1 -0
- package/dist/internal/metadata/service.mjs +416 -0
- package/dist/internal/metadata/service.mjs.map +1 -0
- package/dist/internal/metadata/variables.d.mts +3 -0
- package/dist/internal/metadata/variables.mjs +3 -0
- package/dist/internal/method/arguments.d.mts +48 -0
- package/dist/internal/method/arguments.d.mts.map +1 -0
- package/dist/internal/method/arguments.mjs +216 -0
- package/dist/internal/method/arguments.mjs.map +1 -0
- package/dist/internal/method/operations.d.mts +19 -0
- package/dist/internal/method/operations.d.mts.map +1 -0
- package/dist/internal/method/operations.mjs +111 -0
- package/dist/internal/method/operations.mjs.map +1 -0
- package/dist/internal/monitoring/options.d.mts +30 -0
- package/dist/internal/monitoring/options.d.mts.map +1 -0
- package/dist/internal/monitoring/options.mjs +260 -0
- package/dist/internal/monitoring/options.mjs.map +1 -0
- package/dist/internal/monitoring/requests.d.mts +16 -0
- package/dist/internal/monitoring/requests.d.mts.map +1 -0
- package/dist/internal/monitoring/requests.mjs +53 -0
- package/dist/internal/monitoring/requests.mjs.map +1 -0
- package/dist/internal/monitoring/runtime.d.mts +14 -0
- package/dist/internal/monitoring/runtime.d.mts.map +1 -0
- package/dist/internal/monitoring/runtime.mjs +321 -0
- package/dist/internal/monitoring/runtime.mjs.map +1 -0
- package/dist/internal/monitoring/samples.d.mts +23 -0
- package/dist/internal/monitoring/samples.d.mts.map +1 -0
- package/dist/internal/monitoring/samples.mjs +45 -0
- package/dist/internal/monitoring/samples.mjs.map +1 -0
- package/dist/internal/session/make.d.mts +11 -0
- package/dist/internal/session/make.d.mts.map +1 -0
- package/dist/internal/session/make.mjs +36 -0
- package/dist/internal/session/make.mjs.map +1 -0
- package/dist/internal/session/service.d.mts +10 -0
- package/dist/internal/session/service.d.mts.map +1 -0
- package/dist/internal/session/service.mjs +232 -0
- package/dist/internal/session/service.mjs.map +1 -0
- package/dist/internal/structures/adapter.d.mts +11 -0
- package/dist/internal/structures/adapter.d.mts.map +1 -0
- package/dist/internal/structures/adapter.mjs +37 -0
- package/dist/internal/structures/adapter.mjs.map +1 -0
- package/dist/internal/structures/model.d.mts +21 -0
- package/dist/internal/structures/model.d.mts.map +1 -0
- package/dist/internal/structures/model.mjs +7 -0
- package/dist/internal/structures/model.mjs.map +1 -0
- package/dist/internal/structures/runtime.d.mts +28 -0
- package/dist/internal/structures/runtime.d.mts.map +1 -0
- package/dist/internal/structures/runtime.mjs +119 -0
- package/dist/internal/structures/runtime.mjs.map +1 -0
- package/dist/internal/subscription/options.d.mts +17 -0
- package/dist/internal/subscription/options.d.mts.map +1 -0
- package/dist/internal/subscription/options.mjs +51 -0
- package/dist/internal/subscription/options.mjs.map +1 -0
- package/dist/internal/subscription/runtime.d.mts +15 -0
- package/dist/internal/subscription/runtime.d.mts.map +1 -0
- package/dist/internal/subscription/runtime.mjs +43 -0
- package/dist/internal/subscription/runtime.mjs.map +1 -0
- package/dist/internal/values/codec.d.mts +53 -0
- package/dist/internal/values/codec.d.mts.map +1 -0
- package/dist/internal/values/codec.mjs +117 -0
- package/dist/internal/values/codec.mjs.map +1 -0
- package/dist/internal/values/normalize.d.mts +33 -0
- package/dist/internal/values/normalize.d.mts.map +1 -0
- package/dist/internal/values/normalize.mjs +177 -0
- package/dist/internal/values/normalize.mjs.map +1 -0
- package/dist/internal/values/result.d.mts +16 -0
- package/dist/internal/values/result.d.mts.map +1 -0
- package/dist/internal/values/result.mjs +15 -0
- package/dist/internal/values/result.mjs.map +1 -0
- package/dist/internal/variable/operations.d.mts +50 -0
- package/dist/internal/variable/operations.d.mts.map +1 -0
- package/dist/internal/variable/operations.mjs +192 -0
- package/dist/internal/variable/operations.mjs.map +1 -0
- package/dist/node-opcua.d.mts +2 -0
- package/dist/node-opcua.mjs +3 -0
- package/package.json +57 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
import { isGood, normalizeStatusCode } from "../values/normalize.mjs";
|
|
2
|
+
import { monitorCreateError, monitorRuntimeError, monitorStartupError } from "../../OpcuaError.mjs";
|
|
3
|
+
import { chunksOf } from "../common/collections.mjs";
|
|
4
|
+
import { EventBus } from "../events/wire.mjs";
|
|
5
|
+
import { accessDeniedError } from "../variable/operations.mjs";
|
|
6
|
+
import { applyMonitorOptions, normalizeMonitorItems, validateMonitorOptions } from "./options.mjs";
|
|
7
|
+
import { monitorItems, monitoredItemStatusCode, revisedMonitorItemOptions } from "./requests.mjs";
|
|
8
|
+
import { monitorSampleFromDataValue } from "./samples.mjs";
|
|
9
|
+
import { AttributeIds } from "node-opcua";
|
|
10
|
+
import { Effect, Queue, Result, Stream } from "effect";
|
|
11
|
+
|
|
12
|
+
//#region src/internal/monitoring/runtime.ts
|
|
13
|
+
const makeSubscriptionService = (unsafeRaw, events, structureRuntime, validateVariable) => {
|
|
14
|
+
const finalizingMonitorGroups = /* @__PURE__ */ new WeakSet();
|
|
15
|
+
return {
|
|
16
|
+
monitor: Effect.fnUntraced(function* (items, options) {
|
|
17
|
+
const normalized = yield* normalizeMonitorItems(items);
|
|
18
|
+
const createOptions = yield* validateMonitorOptions(normalized, options);
|
|
19
|
+
const validation = yield* validateStartupItems(unsafeRaw, yield* applyMonitorOptions(normalized, options), options.validation, createOptions, validateVariable);
|
|
20
|
+
if (options.startup === "strict" && validation.failed.size > 0) {
|
|
21
|
+
const report$1 = makeStartupReport(normalized.length, /* @__PURE__ */ new Map(), validation.failed);
|
|
22
|
+
return yield* Effect.fail(monitorCreateError({
|
|
23
|
+
subscriptionId: unsafeRaw.subscriptionId,
|
|
24
|
+
startup: report$1,
|
|
25
|
+
cause: Array.from(validation.failed.values())
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
const notificationQueue = yield* makeMonitorQueue(options.clientBuffer);
|
|
29
|
+
const createdGroups = [];
|
|
30
|
+
const retainedGroups = [];
|
|
31
|
+
const teardowns = [];
|
|
32
|
+
const groupRegistry = {
|
|
33
|
+
add: (group) => {
|
|
34
|
+
createdGroups.push(group);
|
|
35
|
+
},
|
|
36
|
+
remove: (group) => {
|
|
37
|
+
removeCreatedMonitorGroup(createdGroups, group);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
yield* Effect.addFinalizer(() => cleanupMonitor(createdGroups, teardowns, notificationQueue, finalizingMonitorGroups));
|
|
41
|
+
const created = validation.active.length > 0 ? yield* createMonitorChunks(unsafeRaw, validation.active, createOptions, groupRegistry) : [];
|
|
42
|
+
const active = /* @__PURE__ */ new Map();
|
|
43
|
+
const failed = new Map(validation.failed);
|
|
44
|
+
for (const chunk of created) {
|
|
45
|
+
for (const [key, started] of chunk.active) active.set(key, started);
|
|
46
|
+
for (const [key, failure] of chunk.failed) failed.set(key, failure);
|
|
47
|
+
if (chunk.retained) retainedGroups.push(chunk.retained);
|
|
48
|
+
}
|
|
49
|
+
const report = makeStartupReport(normalized.length, active, failed);
|
|
50
|
+
if (options.startup === "strict" && failed.size > 0) {
|
|
51
|
+
yield* cleanupMonitor(createdGroups, teardowns, notificationQueue, finalizingMonitorGroups);
|
|
52
|
+
return yield* Effect.fail(monitorCreateError({
|
|
53
|
+
subscriptionId: unsafeRaw.subscriptionId,
|
|
54
|
+
startup: report,
|
|
55
|
+
cause: Array.from(failed.values())
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
for (const retained of retainedGroups) teardowns.push(wireMonitorGroup(unsafeRaw, events, retained.group, retained.entries, notificationQueue, options.clientBuffer, finalizingMonitorGroups));
|
|
59
|
+
return {
|
|
60
|
+
startup: report,
|
|
61
|
+
samples: Stream.fromQueue(notificationQueue).pipe(Stream.mapEffect(({ entry, dataValue }) => monitorSampleFromDataValue(entry, dataValue, structureRuntime), { concurrency: 1 }))
|
|
62
|
+
};
|
|
63
|
+
}),
|
|
64
|
+
events: Stream.fromPubSub(events),
|
|
65
|
+
unsafeRaw
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
const validateStartupItems = (subscription, items, validation, create, validateVariable) => {
|
|
69
|
+
switch (validation) {
|
|
70
|
+
case "none": return Effect.succeed({
|
|
71
|
+
active: items,
|
|
72
|
+
failed: /* @__PURE__ */ new Map()
|
|
73
|
+
});
|
|
74
|
+
case "access": return validateAccess(subscription, items, create);
|
|
75
|
+
case "strict": return validateStrict(items, validateVariable);
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const validateStrict = (items, validateVariable) => Effect.gen(function* () {
|
|
79
|
+
const active = [];
|
|
80
|
+
const failed = /* @__PURE__ */ new Map();
|
|
81
|
+
for (const item of items) {
|
|
82
|
+
const result = yield* Effect.result(validateVariable(item.def));
|
|
83
|
+
if (Result.isFailure(result)) {
|
|
84
|
+
failed.set(item.key, startupFailure(item, "Validation", result.failure));
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
active.push(item);
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
active,
|
|
91
|
+
failed
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
const validateAccess = (subscription, items, create) => Effect.gen(function* () {
|
|
95
|
+
const results = yield* Effect.forEach(chunksOf(items, create.maxItemsPerRequest), (chunk) => validateAccessChunk(subscription, chunk), { concurrency: create.maxConcurrentRequests });
|
|
96
|
+
const active = [];
|
|
97
|
+
const failed = /* @__PURE__ */ new Map();
|
|
98
|
+
for (const result of results) {
|
|
99
|
+
active.push(...result.active);
|
|
100
|
+
for (const [key, failure] of result.failed) failed.set(key, failure);
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
active,
|
|
104
|
+
failed
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
const validateAccessChunk = (subscription, chunk) => Effect.gen(function* () {
|
|
108
|
+
const nodes = chunk.flatMap((item) => [{
|
|
109
|
+
nodeId: item.rawNodeId,
|
|
110
|
+
attributeId: AttributeIds.AccessLevel
|
|
111
|
+
}, {
|
|
112
|
+
nodeId: item.rawNodeId,
|
|
113
|
+
attributeId: AttributeIds.UserAccessLevel
|
|
114
|
+
}]);
|
|
115
|
+
const readResult = yield* Effect.result(Effect.tryPromise({
|
|
116
|
+
try: () => subscription.session.read(nodes, 0),
|
|
117
|
+
catch: (cause) => cause
|
|
118
|
+
}));
|
|
119
|
+
if (Result.isFailure(readResult)) return {
|
|
120
|
+
active: [],
|
|
121
|
+
failed: new Map(chunk.map((item) => [item.key, startupFailure(item, "Validation", readResult.failure)]))
|
|
122
|
+
};
|
|
123
|
+
const values = Array.isArray(readResult.success) ? readResult.success : [readResult.success];
|
|
124
|
+
const active = [];
|
|
125
|
+
const failed = /* @__PURE__ */ new Map();
|
|
126
|
+
for (let index = 0; index < chunk.length; index++) {
|
|
127
|
+
const item = chunk[index];
|
|
128
|
+
const accessLevelValue = values[index * 2];
|
|
129
|
+
const userAccessLevelValue = values[index * 2 + 1];
|
|
130
|
+
if (!accessLevelValue || !isGood(accessLevelValue.statusCode) || typeof accessLevelValue.value?.value !== "number") {
|
|
131
|
+
failed.set(item.key, startupFailure(item, "Validation", "AccessLevel is unreadable", accessLevelValue?.statusCode));
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const userAccessLevel = userAccessLevelValue && isGood(userAccessLevelValue.statusCode) && typeof userAccessLevelValue.value?.value === "number" ? userAccessLevelValue.value.value : void 0;
|
|
135
|
+
const error = accessDeniedError(item.nodeId, "read", accessLevelValue.value.value, userAccessLevel);
|
|
136
|
+
if (error) {
|
|
137
|
+
failed.set(item.key, startupFailure(item, "Validation", error));
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
active.push(item);
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
active,
|
|
144
|
+
failed
|
|
145
|
+
};
|
|
146
|
+
});
|
|
147
|
+
const createMonitorChunks = (subscription, items, create, groupRegistry) => {
|
|
148
|
+
const chunks = Array.from(groupCompatibleItems(items).values()).flatMap((group) => chunksOf(group, create.maxItemsPerRequest));
|
|
149
|
+
return Effect.forEach(chunks, (chunk) => createMonitorChunk(subscription, chunk, groupRegistry), { concurrency: create.maxConcurrentRequests });
|
|
150
|
+
};
|
|
151
|
+
const createMonitorChunk = (subscription, chunk, groupRegistry) => Effect.gen(function* () {
|
|
152
|
+
const groupResult = yield* Effect.result(monitorItems(subscription, chunk));
|
|
153
|
+
if (Result.isFailure(groupResult)) return {
|
|
154
|
+
active: [],
|
|
155
|
+
failed: chunk.map((item) => [item.key, startupFailure(item, "Create", groupResult.failure)])
|
|
156
|
+
};
|
|
157
|
+
const { group, disposeAbort } = groupResult.success;
|
|
158
|
+
groupRegistry.add(group);
|
|
159
|
+
disposeAbort();
|
|
160
|
+
const active = [];
|
|
161
|
+
const failed = [];
|
|
162
|
+
const entries = [];
|
|
163
|
+
const retainedNodeIds = [];
|
|
164
|
+
for (let index = 0; index < chunk.length; index++) {
|
|
165
|
+
const item = chunk[index];
|
|
166
|
+
const monitoredItem = group.monitoredItems[index];
|
|
167
|
+
const statusCode = monitoredItemStatusCode(monitoredItem);
|
|
168
|
+
if (!isGood(statusCode)) {
|
|
169
|
+
failed.push([item.key, startupFailure(item, "Create", monitoredItem?.result, statusCode)]);
|
|
170
|
+
entries.push(void 0);
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
active.push([item.key, {
|
|
174
|
+
key: item.key,
|
|
175
|
+
nodeId: item.nodeId,
|
|
176
|
+
requested: item.requested,
|
|
177
|
+
revised: revisedMonitorItemOptions(monitoredItem)
|
|
178
|
+
}]);
|
|
179
|
+
entries.push({
|
|
180
|
+
key: item.key,
|
|
181
|
+
nodeId: item.nodeId,
|
|
182
|
+
def: item.def,
|
|
183
|
+
timestamps: item.requested.timestamps
|
|
184
|
+
});
|
|
185
|
+
retainedNodeIds.push(item.nodeId);
|
|
186
|
+
}
|
|
187
|
+
if (retainedNodeIds.length === 0) {
|
|
188
|
+
yield* terminateCreatedMonitorGroup(group, groupRegistry);
|
|
189
|
+
return {
|
|
190
|
+
active,
|
|
191
|
+
failed
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
active,
|
|
196
|
+
failed,
|
|
197
|
+
retained: {
|
|
198
|
+
group,
|
|
199
|
+
entries,
|
|
200
|
+
nodeIds: retainedNodeIds
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
});
|
|
204
|
+
const wireMonitorGroup = (subscription, events, group, entries, queue, policy, finalizingMonitorGroups) => {
|
|
205
|
+
const nodeIds = entries.flatMap((entry) => entry ? [entry.nodeId] : []);
|
|
206
|
+
const failRuntime = (cause) => {
|
|
207
|
+
if (finalizingMonitorGroups.has(group)) return;
|
|
208
|
+
const error = monitorRuntimeError({
|
|
209
|
+
subscriptionId: subscription.subscriptionId,
|
|
210
|
+
nodeIds,
|
|
211
|
+
cause
|
|
212
|
+
});
|
|
213
|
+
EventBus.publishUnsafe(events, {
|
|
214
|
+
_tag: "InternalError",
|
|
215
|
+
subscriptionId: subscription.subscriptionId,
|
|
216
|
+
cause
|
|
217
|
+
});
|
|
218
|
+
Effect.runSync(Queue.fail(queue, error));
|
|
219
|
+
};
|
|
220
|
+
const onChanged = (_item, dataValue, index) => {
|
|
221
|
+
const entry = entries[index];
|
|
222
|
+
if (!entry) return;
|
|
223
|
+
offerMonitorNotification(subscription, events, queue, policy, {
|
|
224
|
+
entry,
|
|
225
|
+
dataValue
|
|
226
|
+
});
|
|
227
|
+
};
|
|
228
|
+
const onError = (message) => {
|
|
229
|
+
failRuntime(message);
|
|
230
|
+
};
|
|
231
|
+
const onTerminatedGroup = (cause) => {
|
|
232
|
+
if (finalizingMonitorGroups.has(group)) return;
|
|
233
|
+
EventBus.publishUnsafe(events, {
|
|
234
|
+
_tag: "MonitorItemsTerminated",
|
|
235
|
+
subscriptionId: subscription.subscriptionId,
|
|
236
|
+
nodeIds
|
|
237
|
+
});
|
|
238
|
+
failRuntime(cause);
|
|
239
|
+
};
|
|
240
|
+
group.on("changed", onChanged);
|
|
241
|
+
group.on("err", onError);
|
|
242
|
+
group.on("terminated", onTerminatedGroup);
|
|
243
|
+
EventBus.publishUnsafe(events, {
|
|
244
|
+
_tag: "MonitorItemsCreated",
|
|
245
|
+
subscriptionId: subscription.subscriptionId,
|
|
246
|
+
nodeIds
|
|
247
|
+
});
|
|
248
|
+
return () => {
|
|
249
|
+
group.removeListener("changed", onChanged);
|
|
250
|
+
group.removeListener("err", onError);
|
|
251
|
+
group.removeListener("terminated", onTerminatedGroup);
|
|
252
|
+
};
|
|
253
|
+
};
|
|
254
|
+
const offerMonitorNotification = (subscription, events, queue, policy, notification) => {
|
|
255
|
+
const willDrop = policy._tag === "Sliding" && Queue.sizeUnsafe(queue) >= policy.capacity;
|
|
256
|
+
const offered = Queue.offerUnsafe(queue, notification);
|
|
257
|
+
if (willDrop || !offered) EventBus.publishUnsafe(events, {
|
|
258
|
+
_tag: "ClientBufferDropped",
|
|
259
|
+
subscriptionId: subscription.subscriptionId,
|
|
260
|
+
nodeId: notification.entry.nodeId
|
|
261
|
+
});
|
|
262
|
+
};
|
|
263
|
+
const cleanupMonitor = (createdGroups, teardowns, queue, finalizingMonitorGroups) => Effect.gen(function* () {
|
|
264
|
+
const listeners = teardowns.splice(0);
|
|
265
|
+
for (const teardown of listeners) yield* Effect.sync(teardown);
|
|
266
|
+
const groups = createdGroups.splice(0);
|
|
267
|
+
for (const group of groups) {
|
|
268
|
+
yield* Effect.sync(() => {
|
|
269
|
+
finalizingMonitorGroups.add(group);
|
|
270
|
+
});
|
|
271
|
+
yield* terminateMonitorGroup(group);
|
|
272
|
+
}
|
|
273
|
+
yield* Queue.shutdown(queue);
|
|
274
|
+
}).pipe(Effect.ignore);
|
|
275
|
+
const makeMonitorQueue = (policy) => policy._tag === "Sliding" ? Queue.sliding(policy.capacity) : Queue.dropping(policy.capacity);
|
|
276
|
+
const groupCompatibleItems = (items) => {
|
|
277
|
+
const groups = /* @__PURE__ */ new Map();
|
|
278
|
+
for (const item of items) {
|
|
279
|
+
const group = groups.get(item.compatibilityKey);
|
|
280
|
+
if (group) group.push(item);
|
|
281
|
+
else groups.set(item.compatibilityKey, [item]);
|
|
282
|
+
}
|
|
283
|
+
return groups;
|
|
284
|
+
};
|
|
285
|
+
const startupFailure = (item, phase, cause, statusCode) => ({
|
|
286
|
+
key: item.key,
|
|
287
|
+
nodeId: item.nodeId,
|
|
288
|
+
requested: item.requested,
|
|
289
|
+
error: monitorStartupError({
|
|
290
|
+
phase,
|
|
291
|
+
key: item.key,
|
|
292
|
+
nodeId: item.nodeId,
|
|
293
|
+
statusCode,
|
|
294
|
+
status: statusCode ? normalizeStatusCode(statusCode) : void 0,
|
|
295
|
+
cause
|
|
296
|
+
})
|
|
297
|
+
});
|
|
298
|
+
const makeStartupReport = (requested, active, failed) => ({
|
|
299
|
+
ok: failed.size === 0,
|
|
300
|
+
requested,
|
|
301
|
+
activeCount: active.size,
|
|
302
|
+
failedCount: failed.size,
|
|
303
|
+
active,
|
|
304
|
+
failed
|
|
305
|
+
});
|
|
306
|
+
const terminateMonitorGroup = (group) => Effect.tryPromise({
|
|
307
|
+
try: () => group.terminate(),
|
|
308
|
+
catch: (cause) => cause
|
|
309
|
+
}).pipe(Effect.ignore);
|
|
310
|
+
const terminateCreatedMonitorGroup = (group, registry) => Effect.uninterruptible(Effect.gen(function* () {
|
|
311
|
+
yield* terminateMonitorGroup(group);
|
|
312
|
+
yield* Effect.sync(() => registry.remove(group));
|
|
313
|
+
}));
|
|
314
|
+
const removeCreatedMonitorGroup = (groups, group) => {
|
|
315
|
+
const index = groups.indexOf(group);
|
|
316
|
+
if (index >= 0) groups.splice(index, 1);
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
//#endregion
|
|
320
|
+
export { makeSubscriptionService };
|
|
321
|
+
//# sourceMappingURL=runtime.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.mjs","names":["report","OpcuaError.monitorCreateError","createdGroups: Array<ClientMonitoredItemGroup>","retainedGroups: Array<RetainedMonitorGroup<Items>>","teardowns: Array<() => void>","groupRegistry: MonitorGroupRegistry","active: Array<EffectiveMonitorItem<Items>>","VariableOperations.accessDeniedError","active: Array<readonly [MonitorKey<Items>, MonitorStarted]>","failed: Array<readonly [MonitorKey<Items>, MonitorStartupFailure]>","entries: Array<WireMonitorEntry<Items> | undefined>","retainedNodeIds: Array<NodeIdString>","OpcuaError.monitorRuntimeError","OpcuaError.monitorStartupError"],"sources":["../../../src/internal/monitoring/runtime.ts"],"sourcesContent":["import {\n AttributeIds,\n type ClientMonitoredItemBase,\n type ClientMonitoredItemGroup,\n type ClientSubscription,\n type DataValue,\n type StatusCode,\n} from \"node-opcua\";\nimport { Effect, PubSub, Queue, Result, Scope, Stream } from \"effect\";\n\nimport * as OpcuaError from \"../../OpcuaError.js\";\nimport type * as OpcuaVariable from \"../../OpcuaVariable.js\";\nimport type {\n ActiveMonitor,\n BufferPolicy,\n MonitorItemDictionary,\n MonitorOptions,\n MonitorStartupFailure,\n MonitorStartupReport,\n MonitorStarted,\n MonitorValidation,\n OpcuaSubscription,\n} from \"../../OpcuaSubscription.js\";\nimport { chunksOf } from \"../common/collections.js\";\nimport type { NodeIdString } from \"../common/node-id.js\";\nimport type { OpcuaSubscriptionEvent } from \"../events/model.js\";\nimport { EventBus } from \"../events/wire.js\";\nimport type { OpcuaStructureRuntime } from \"../structures/runtime.js\";\nimport { isGood, normalizeStatusCode } from \"../values/normalize.js\";\nimport * as VariableOperations from \"../variable/operations.js\";\nimport {\n applyMonitorOptions,\n normalizeMonitorItems,\n validateMonitorOptions,\n type EffectiveMonitorItem,\n type NormalizedCreateOptions,\n} from \"./options.js\";\nimport {\n monitoredItemStatusCode,\n monitorItems,\n revisedMonitorItemOptions,\n} from \"./requests.js\";\nimport {\n monitorSampleFromDataValue,\n type MonitorKey,\n type RawMonitorNotification,\n type WireMonitorEntry,\n} from \"./samples.js\";\n\nexport type ValidateVariable = <\n const Def extends OpcuaVariable.ReadableVariableDef,\n>(\n def: Def,\n) => Effect.Effect<\n unknown,\n | OpcuaError.OpcuaAccessDeniedError\n | OpcuaError.OpcuaConfigurationError\n | OpcuaError.OpcuaServiceError\n>;\n\ntype ValidationResult<Items> = {\n readonly active: ReadonlyArray<EffectiveMonitorItem<Items>>;\n readonly failed: Map<MonitorKey<Items>, MonitorStartupFailure>;\n};\n\ntype RetainedMonitorGroup<Items> = {\n readonly group: ClientMonitoredItemGroup;\n readonly entries: ReadonlyArray<WireMonitorEntry<Items> | undefined>;\n readonly nodeIds: ReadonlyArray<NodeIdString>;\n};\n\ntype CreatedChunk<Items> = {\n readonly retained?: RetainedMonitorGroup<Items>;\n readonly active: ReadonlyArray<readonly [MonitorKey<Items>, MonitorStarted]>;\n readonly failed: ReadonlyArray<\n readonly [MonitorKey<Items>, MonitorStartupFailure]\n >;\n};\n\ntype MonitorGroupRegistry = {\n readonly add: (group: ClientMonitoredItemGroup) => void;\n readonly remove: (group: ClientMonitoredItemGroup) => void;\n};\n\nexport const makeSubscriptionService = (\n unsafeRaw: ClientSubscription,\n events: PubSub.PubSub<OpcuaSubscriptionEvent>,\n structureRuntime: OpcuaStructureRuntime,\n validateVariable: ValidateVariable,\n): OpcuaSubscription => {\n const finalizingMonitorGroups = new WeakSet<ClientMonitoredItemGroup>();\n\n const monitor = Effect.fnUntraced(function* <\n const Items extends MonitorItemDictionary,\n >(\n items: Items,\n options: MonitorOptions<Items>,\n ): Effect.fn.Return<\n ActiveMonitor<Items>,\n | OpcuaError.OpcuaMonitorCreateError<Items>\n | OpcuaError.OpcuaMonitorConfigurationError,\n Scope.Scope\n > {\n const normalized = yield* normalizeMonitorItems(items);\n const createOptions = yield* validateMonitorOptions(normalized, options);\n const effective = yield* applyMonitorOptions(normalized, options);\n const validation = yield* validateStartupItems(\n unsafeRaw,\n effective,\n options.validation,\n createOptions,\n validateVariable,\n );\n\n if (options.startup === \"strict\" && validation.failed.size > 0) {\n const report = makeStartupReport<Items>(\n normalized.length,\n new Map(),\n validation.failed,\n );\n return yield* Effect.fail(\n OpcuaError.monitorCreateError<Items>({\n subscriptionId: unsafeRaw.subscriptionId,\n startup: report,\n cause: Array.from(validation.failed.values()),\n }),\n );\n }\n\n const notificationQueue = yield* makeMonitorQueue<\n RawMonitorNotification<Items>,\n OpcuaError.OpcuaMonitorRuntimeError\n >(options.clientBuffer);\n const createdGroups: Array<ClientMonitoredItemGroup> = [];\n const retainedGroups: Array<RetainedMonitorGroup<Items>> = [];\n const teardowns: Array<() => void> = [];\n const groupRegistry: MonitorGroupRegistry = {\n add: (group) => {\n createdGroups.push(group);\n },\n remove: (group) => {\n removeCreatedMonitorGroup(createdGroups, group);\n },\n };\n\n yield* Effect.addFinalizer(() =>\n cleanupMonitor(\n createdGroups,\n teardowns,\n notificationQueue,\n finalizingMonitorGroups,\n ),\n );\n\n const created =\n validation.active.length > 0\n ? yield* createMonitorChunks(\n unsafeRaw,\n validation.active,\n createOptions,\n groupRegistry,\n )\n : [];\n const active = new Map<MonitorKey<Items>, MonitorStarted>();\n const failed = new Map(validation.failed);\n\n for (const chunk of created) {\n for (const [key, started] of chunk.active) active.set(key, started);\n for (const [key, failure] of chunk.failed) failed.set(key, failure);\n if (chunk.retained) retainedGroups.push(chunk.retained);\n }\n\n const report = makeStartupReport<Items>(normalized.length, active, failed);\n\n if (options.startup === \"strict\" && failed.size > 0) {\n yield* cleanupMonitor(\n createdGroups,\n teardowns,\n notificationQueue,\n finalizingMonitorGroups,\n );\n return yield* Effect.fail(\n OpcuaError.monitorCreateError<Items>({\n subscriptionId: unsafeRaw.subscriptionId,\n startup: report,\n cause: Array.from(failed.values()),\n }),\n );\n }\n\n for (const retained of retainedGroups) {\n teardowns.push(\n wireMonitorGroup(\n unsafeRaw,\n events,\n retained.group,\n retained.entries,\n notificationQueue,\n options.clientBuffer,\n finalizingMonitorGroups,\n ),\n );\n }\n\n return {\n startup: report,\n samples: Stream.fromQueue(notificationQueue).pipe(\n Stream.mapEffect(\n ({ entry, dataValue }) =>\n monitorSampleFromDataValue(entry, dataValue, structureRuntime),\n { concurrency: 1 },\n ),\n ),\n };\n });\n\n return {\n monitor: monitor as OpcuaSubscription[\"monitor\"],\n events: Stream.fromPubSub(events),\n unsafeRaw,\n };\n};\n\nconst validateStartupItems = <Items>(\n subscription: ClientSubscription,\n items: ReadonlyArray<EffectiveMonitorItem<Items>>,\n validation: MonitorValidation,\n create: NormalizedCreateOptions,\n validateVariable: ValidateVariable,\n): Effect.Effect<ValidationResult<Items>, never> => {\n switch (validation) {\n case \"none\":\n return Effect.succeed({ active: items, failed: new Map() });\n case \"access\":\n return validateAccess(subscription, items, create);\n case \"strict\":\n return validateStrict(items, validateVariable);\n }\n};\n\nconst validateStrict = <Items>(\n items: ReadonlyArray<EffectiveMonitorItem<Items>>,\n validateVariable: ValidateVariable,\n): Effect.Effect<ValidationResult<Items>, never> =>\n Effect.gen(function* () {\n const active: Array<EffectiveMonitorItem<Items>> = [];\n const failed = new Map<MonitorKey<Items>, MonitorStartupFailure>();\n for (const item of items) {\n const result = yield* Effect.result(validateVariable(item.def));\n if (Result.isFailure(result)) {\n failed.set(\n item.key,\n startupFailure(item, \"Validation\", result.failure),\n );\n continue;\n }\n active.push(item);\n }\n return { active, failed };\n });\n\nconst validateAccess = <Items>(\n subscription: ClientSubscription,\n items: ReadonlyArray<EffectiveMonitorItem<Items>>,\n create: NormalizedCreateOptions,\n): Effect.Effect<ValidationResult<Items>, never> =>\n Effect.gen(function* () {\n const results = yield* Effect.forEach(\n chunksOf(items, create.maxItemsPerRequest),\n (chunk) => validateAccessChunk(subscription, chunk),\n {\n concurrency: create.maxConcurrentRequests,\n },\n );\n const active: Array<EffectiveMonitorItem<Items>> = [];\n const failed = new Map<MonitorKey<Items>, MonitorStartupFailure>();\n for (const result of results) {\n active.push(...result.active);\n for (const [key, failure] of result.failed) failed.set(key, failure);\n }\n return { active, failed };\n });\n\nconst validateAccessChunk = <Items>(\n subscription: ClientSubscription,\n chunk: ReadonlyArray<EffectiveMonitorItem<Items>>,\n): Effect.Effect<ValidationResult<Items>, never> =>\n Effect.gen(function* () {\n const nodes = chunk.flatMap((item) => [\n { nodeId: item.rawNodeId, attributeId: AttributeIds.AccessLevel },\n { nodeId: item.rawNodeId, attributeId: AttributeIds.UserAccessLevel },\n ]);\n const readResult = yield* Effect.result(\n Effect.tryPromise({\n try: () => subscription.session.read(nodes, 0),\n catch: (cause) => cause,\n }),\n );\n if (Result.isFailure(readResult)) {\n return {\n active: [],\n failed: new Map(\n chunk.map((item) => [\n item.key,\n startupFailure(item, \"Validation\", readResult.failure),\n ]),\n ),\n };\n }\n\n const values = Array.isArray(readResult.success)\n ? readResult.success\n : [readResult.success];\n const active: Array<EffectiveMonitorItem<Items>> = [];\n const failed = new Map<MonitorKey<Items>, MonitorStartupFailure>();\n for (let index = 0; index < chunk.length; index++) {\n const item = chunk[index]!;\n const accessLevelValue = values[index * 2];\n const userAccessLevelValue = values[index * 2 + 1];\n if (\n !accessLevelValue ||\n !isGood(accessLevelValue.statusCode) ||\n typeof accessLevelValue.value?.value !== \"number\"\n ) {\n failed.set(\n item.key,\n startupFailure(\n item,\n \"Validation\",\n \"AccessLevel is unreadable\",\n accessLevelValue?.statusCode,\n ),\n );\n continue;\n }\n const userAccessLevel =\n userAccessLevelValue &&\n isGood(userAccessLevelValue.statusCode) &&\n typeof userAccessLevelValue.value?.value === \"number\"\n ? (userAccessLevelValue.value.value as number)\n : undefined;\n const error = VariableOperations.accessDeniedError(\n item.nodeId,\n \"read\",\n accessLevelValue.value.value as number,\n userAccessLevel,\n );\n if (error) {\n failed.set(item.key, startupFailure(item, \"Validation\", error));\n continue;\n }\n active.push(item);\n }\n return { active, failed };\n });\n\nconst createMonitorChunks = <Items>(\n subscription: ClientSubscription,\n items: ReadonlyArray<EffectiveMonitorItem<Items>>,\n create: NormalizedCreateOptions,\n groupRegistry: MonitorGroupRegistry,\n): Effect.Effect<ReadonlyArray<CreatedChunk<Items>>, never> => {\n const chunks = Array.from(groupCompatibleItems(items).values()).flatMap(\n (group) => chunksOf(group, create.maxItemsPerRequest),\n );\n return Effect.forEach(\n chunks,\n (chunk) => createMonitorChunk(subscription, chunk, groupRegistry),\n {\n concurrency: create.maxConcurrentRequests,\n },\n );\n};\n\nconst createMonitorChunk = <Items>(\n subscription: ClientSubscription,\n chunk: ReadonlyArray<EffectiveMonitorItem<Items>>,\n groupRegistry: MonitorGroupRegistry,\n): Effect.Effect<CreatedChunk<Items>, never> =>\n Effect.gen(function* () {\n const groupResult = yield* Effect.result(monitorItems(subscription, chunk));\n if (Result.isFailure(groupResult)) {\n return {\n active: [],\n failed: chunk.map((item) => [\n item.key,\n startupFailure(item, \"Create\", groupResult.failure),\n ]),\n };\n }\n\n const { group, disposeAbort } = groupResult.success;\n groupRegistry.add(group);\n disposeAbort();\n const active: Array<readonly [MonitorKey<Items>, MonitorStarted]> = [];\n const failed: Array<readonly [MonitorKey<Items>, MonitorStartupFailure]> =\n [];\n const entries: Array<WireMonitorEntry<Items> | undefined> = [];\n const retainedNodeIds: Array<NodeIdString> = [];\n\n for (let index = 0; index < chunk.length; index++) {\n const item = chunk[index]!;\n const monitoredItem = group.monitoredItems[index];\n const statusCode = monitoredItemStatusCode(monitoredItem);\n if (!isGood(statusCode)) {\n failed.push([\n item.key,\n startupFailure(item, \"Create\", monitoredItem?.result, statusCode),\n ]);\n entries.push(undefined);\n continue;\n }\n active.push([\n item.key,\n {\n key: item.key,\n nodeId: item.nodeId,\n requested: item.requested,\n revised: revisedMonitorItemOptions(monitoredItem),\n },\n ]);\n entries.push({\n key: item.key,\n nodeId: item.nodeId,\n def: item.def,\n timestamps: item.requested.timestamps,\n });\n retainedNodeIds.push(item.nodeId);\n }\n\n if (retainedNodeIds.length === 0) {\n yield* terminateCreatedMonitorGroup(group, groupRegistry);\n return { active, failed };\n }\n return {\n active,\n failed,\n retained: {\n group,\n entries,\n nodeIds: retainedNodeIds,\n },\n };\n });\n\nconst wireMonitorGroup = <Items>(\n subscription: ClientSubscription,\n events: PubSub.PubSub<OpcuaSubscriptionEvent>,\n group: ClientMonitoredItemGroup,\n entries: ReadonlyArray<WireMonitorEntry<Items> | undefined>,\n queue: Queue.Queue<\n RawMonitorNotification<Items>,\n OpcuaError.OpcuaMonitorRuntimeError\n >,\n policy: BufferPolicy,\n finalizingMonitorGroups: WeakSet<ClientMonitoredItemGroup>,\n) => {\n const nodeIds = entries.flatMap((entry) => (entry ? [entry.nodeId] : []));\n const failRuntime = (cause: unknown) => {\n if (finalizingMonitorGroups.has(group)) return;\n const error = OpcuaError.monitorRuntimeError({\n subscriptionId: subscription.subscriptionId,\n nodeIds,\n cause,\n });\n EventBus.publishUnsafe(events, {\n _tag: \"InternalError\",\n subscriptionId: subscription.subscriptionId,\n cause,\n });\n Effect.runSync(Queue.fail(queue, error));\n };\n const onChanged = (\n _item: ClientMonitoredItemBase,\n dataValue: DataValue,\n index: number,\n ) => {\n const entry = entries[index];\n if (!entry) return;\n offerMonitorNotification(subscription, events, queue, policy, {\n entry,\n dataValue,\n });\n };\n const onError = (message: unknown) => {\n failRuntime(message);\n };\n const onTerminatedGroup = (cause: unknown) => {\n if (finalizingMonitorGroups.has(group)) return;\n EventBus.publishUnsafe(events, {\n _tag: \"MonitorItemsTerminated\",\n subscriptionId: subscription.subscriptionId,\n nodeIds,\n });\n failRuntime(cause);\n };\n group.on(\"changed\", onChanged);\n group.on(\"err\", onError);\n group.on(\"terminated\", onTerminatedGroup);\n EventBus.publishUnsafe(events, {\n _tag: \"MonitorItemsCreated\",\n subscriptionId: subscription.subscriptionId,\n nodeIds,\n });\n return () => {\n group.removeListener(\"changed\", onChanged);\n group.removeListener(\"err\", onError);\n group.removeListener(\"terminated\", onTerminatedGroup);\n };\n};\n\nconst offerMonitorNotification = <Items>(\n subscription: ClientSubscription,\n events: PubSub.PubSub<OpcuaSubscriptionEvent>,\n queue: Queue.Queue<\n RawMonitorNotification<Items>,\n OpcuaError.OpcuaMonitorRuntimeError\n >,\n policy: BufferPolicy,\n notification: RawMonitorNotification<Items>,\n) => {\n const willDrop =\n policy._tag === \"Sliding\" && Queue.sizeUnsafe(queue) >= policy.capacity;\n const offered = Queue.offerUnsafe(queue, notification);\n if (willDrop || !offered) {\n EventBus.publishUnsafe(events, {\n _tag: \"ClientBufferDropped\",\n subscriptionId: subscription.subscriptionId,\n nodeId: notification.entry.nodeId,\n });\n }\n};\n\nconst cleanupMonitor = <Items>(\n createdGroups: Array<ClientMonitoredItemGroup>,\n teardowns: Array<() => void>,\n queue: Queue.Queue<\n RawMonitorNotification<Items>,\n OpcuaError.OpcuaMonitorRuntimeError\n >,\n finalizingMonitorGroups: WeakSet<ClientMonitoredItemGroup>,\n) =>\n Effect.gen(function* () {\n const listeners = teardowns.splice(0);\n for (const teardown of listeners) yield* Effect.sync(teardown);\n const groups = createdGroups.splice(0);\n for (const group of groups) {\n yield* Effect.sync(() => {\n finalizingMonitorGroups.add(group);\n });\n yield* terminateMonitorGroup(group);\n }\n yield* Queue.shutdown(queue);\n }).pipe(Effect.ignore);\n\nconst makeMonitorQueue = <A, E>(policy: BufferPolicy) =>\n policy._tag === \"Sliding\"\n ? Queue.sliding<A, E>(policy.capacity)\n : Queue.dropping<A, E>(policy.capacity);\n\nconst groupCompatibleItems = <Items>(\n items: ReadonlyArray<EffectiveMonitorItem<Items>>,\n) => {\n const groups = new Map<string, Array<EffectiveMonitorItem<Items>>>();\n for (const item of items) {\n const group = groups.get(item.compatibilityKey);\n if (group) {\n group.push(item);\n } else {\n groups.set(item.compatibilityKey, [item]);\n }\n }\n return groups;\n};\n\nconst startupFailure = <Items>(\n item: EffectiveMonitorItem<Items>,\n phase: \"Validation\" | \"Create\",\n cause: unknown,\n statusCode?: StatusCode,\n): MonitorStartupFailure => ({\n key: item.key,\n nodeId: item.nodeId,\n requested: item.requested,\n error: OpcuaError.monitorStartupError({\n phase,\n key: item.key,\n nodeId: item.nodeId,\n statusCode,\n status: statusCode ? normalizeStatusCode(statusCode) : undefined,\n cause,\n }),\n});\n\nconst makeStartupReport = <Items>(\n requested: number,\n active: ReadonlyMap<MonitorKey<Items>, MonitorStarted>,\n failed: ReadonlyMap<MonitorKey<Items>, MonitorStartupFailure>,\n): MonitorStartupReport<Items> => ({\n ok: failed.size === 0,\n requested,\n activeCount: active.size,\n failedCount: failed.size,\n active,\n failed,\n});\n\nconst terminateMonitorGroup = (group: ClientMonitoredItemGroup) =>\n Effect.tryPromise({\n try: () => group.terminate(),\n catch: (cause) => cause,\n }).pipe(Effect.ignore);\n\nconst terminateCreatedMonitorGroup = (\n group: ClientMonitoredItemGroup,\n registry: MonitorGroupRegistry,\n) =>\n Effect.uninterruptible(\n Effect.gen(function* () {\n yield* terminateMonitorGroup(group);\n yield* Effect.sync(() => registry.remove(group));\n }),\n );\n\nconst removeCreatedMonitorGroup = (\n groups: Array<ClientMonitoredItemGroup>,\n group: ClientMonitoredItemGroup,\n) => {\n const index = groups.indexOf(group);\n if (index >= 0) groups.splice(index, 1);\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { NodeIdString, ReadableVariableDef } from "../../OpcuaVariable.mjs";
|
|
2
|
+
import "../common/node-id.mjs";
|
|
3
|
+
import { OpcuaStructureRuntime } from "../structures/runtime.mjs";
|
|
4
|
+
import { MonitorSample, MonitorTimestamps } from "../../OpcuaSubscription.mjs";
|
|
5
|
+
import { DataValue } from "node-opcua";
|
|
6
|
+
import { Effect } from "effect";
|
|
7
|
+
|
|
8
|
+
//#region src/internal/monitoring/samples.d.ts
|
|
9
|
+
type MonitorKey<Items> = keyof Items & string;
|
|
10
|
+
type WireMonitorEntry<Items> = {
|
|
11
|
+
readonly key: MonitorKey<Items>;
|
|
12
|
+
readonly nodeId: NodeIdString;
|
|
13
|
+
readonly def: ReadableVariableDef;
|
|
14
|
+
readonly timestamps: MonitorTimestamps;
|
|
15
|
+
};
|
|
16
|
+
type RawMonitorNotification<Items> = {
|
|
17
|
+
readonly entry: WireMonitorEntry<Items>;
|
|
18
|
+
readonly dataValue: DataValue;
|
|
19
|
+
};
|
|
20
|
+
declare const monitorSampleFromDataValue: <Items>(entry: WireMonitorEntry<Items>, dataValue: DataValue, structureRuntime: OpcuaStructureRuntime) => Effect.Effect<MonitorSample<Items>>;
|
|
21
|
+
//#endregion
|
|
22
|
+
export { MonitorKey, RawMonitorNotification, WireMonitorEntry, monitorSampleFromDataValue };
|
|
23
|
+
//# sourceMappingURL=samples.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"samples.d.mts","names":[],"sources":["../../../src/internal/monitoring/samples.ts"],"sourcesContent":[],"mappings":";;;;;;;;KAYY,0BAA0B;KAE1B;EAFA,SAAA,GAAA,EAGI,UAHM,CAGK,KAHL,CAAgB;EAE1B,SAAA,MAAA,EAEO,YAFS;EACD,SAAA,GAAA,EAEX,mBAFW;EAAX,SAAA,UAAA,EAGO,iBAHP;CACG;AACH,KAIJ,sBAJI,CAAA,KAAA,CAAA,GAAA;EACO,SAAA,KAAA,EAIL,gBAJK,CAIY,KAJZ,CAAA;EAAmC,SAAA,SAAA,EAKpC,SALoC;AAG1D,CAAA;AACmC,cAItB,0BAJsB,EAAA,CAAA,KAAA,CAAA,CAAA,KAAA,EAK1B,gBAL0B,CAKT,KALS,CAAA,EAAA,SAAA,EAMtB,SANsB,EAAA,gBAAA,EAOf,qBAPe,EAAA,GAQhC,MAAA,CAAO,MARyB,CAQlB,aARkB,CAQc,KARd,CAAA,CAAA"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { normalizeStatusCode } from "../values/normalize.mjs";
|
|
2
|
+
import { decodeError } from "../../OpcuaError.mjs";
|
|
3
|
+
import { Codec } from "../values/codec.mjs";
|
|
4
|
+
import { resultFromStatusAndDecode } from "../values/result.mjs";
|
|
5
|
+
import { Effect } from "effect";
|
|
6
|
+
|
|
7
|
+
//#region src/internal/monitoring/samples.ts
|
|
8
|
+
const monitorSampleFromDataValue = (entry, dataValue, structureRuntime) => Effect.suspend(() => {
|
|
9
|
+
const base = monitorSampleBase(entry, dataValue);
|
|
10
|
+
return resultFromStatusAndDecode({
|
|
11
|
+
statusCode: dataValue.statusCode,
|
|
12
|
+
status: base,
|
|
13
|
+
decode: Codec.decode(entry.def.codec, dataValue.value, dataValue, structureRuntime),
|
|
14
|
+
nonGoodStatus: (base$1) => ({
|
|
15
|
+
_tag: "Status",
|
|
16
|
+
...base$1
|
|
17
|
+
}),
|
|
18
|
+
decodeError: (error, base$1) => ({
|
|
19
|
+
_tag: "DecodeError",
|
|
20
|
+
...base$1,
|
|
21
|
+
error: decodeError({
|
|
22
|
+
nodeId: entry.nodeId,
|
|
23
|
+
cause: error
|
|
24
|
+
}),
|
|
25
|
+
rawValue: dataValue.value?.value
|
|
26
|
+
}),
|
|
27
|
+
value: (value) => ({
|
|
28
|
+
_tag: "Value",
|
|
29
|
+
...base,
|
|
30
|
+
value
|
|
31
|
+
})
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
const monitorSampleBase = (entry, dataValue) => ({
|
|
35
|
+
key: entry.key,
|
|
36
|
+
nodeId: entry.nodeId,
|
|
37
|
+
status: normalizeStatusCode(dataValue.statusCode),
|
|
38
|
+
sourceTimestamp: entry.timestamps === "source" || entry.timestamps === "both" ? dateTimestamp(dataValue.sourceTimestamp) : void 0,
|
|
39
|
+
serverTimestamp: entry.timestamps === "server" || entry.timestamps === "both" ? dateTimestamp(dataValue.serverTimestamp) : void 0
|
|
40
|
+
});
|
|
41
|
+
const dateTimestamp = (timestamp) => timestamp instanceof Date ? timestamp : void 0;
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
export { monitorSampleFromDataValue };
|
|
45
|
+
//# sourceMappingURL=samples.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"samples.mjs","names":["base","OpcuaError.decodeError"],"sources":["../../../src/internal/monitoring/samples.ts"],"sourcesContent":["import type { DataValue } from \"node-opcua\";\nimport { Effect } from \"effect\";\n\nimport * as OpcuaError from \"../../OpcuaError.js\";\nimport type * as OpcuaSubscription from \"../../OpcuaSubscription.js\";\nimport type * as OpcuaVariable from \"../../OpcuaVariable.js\";\nimport type { NodeIdString } from \"../common/node-id.js\";\nimport type { OpcuaStructureRuntime } from \"../structures/runtime.js\";\nimport { Codec } from \"../values/codec.js\";\nimport { normalizeStatusCode } from \"../values/normalize.js\";\nimport { resultFromStatusAndDecode } from \"../values/result.js\";\n\nexport type MonitorKey<Items> = keyof Items & string;\n\nexport type WireMonitorEntry<Items> = {\n readonly key: MonitorKey<Items>;\n readonly nodeId: NodeIdString;\n readonly def: OpcuaVariable.ReadableVariableDef;\n readonly timestamps: OpcuaSubscription.MonitorTimestamps;\n};\n\nexport type RawMonitorNotification<Items> = {\n readonly entry: WireMonitorEntry<Items>;\n readonly dataValue: DataValue;\n};\n\nexport const monitorSampleFromDataValue = <Items>(\n entry: WireMonitorEntry<Items>,\n dataValue: DataValue,\n structureRuntime: OpcuaStructureRuntime,\n): Effect.Effect<OpcuaSubscription.MonitorSample<Items>> =>\n Effect.suspend(() => {\n const base = monitorSampleBase(entry, dataValue);\n return resultFromStatusAndDecode<\n unknown,\n typeof base,\n OpcuaSubscription.MonitorSample<Items>\n >({\n statusCode: dataValue.statusCode,\n status: base,\n decode: Codec.decode(\n entry.def.codec,\n dataValue.value,\n dataValue,\n structureRuntime,\n ),\n nonGoodStatus: (base) =>\n ({ _tag: \"Status\", ...base }) as OpcuaSubscription.MonitorSample<Items>,\n decodeError: (error, base) =>\n ({\n _tag: \"DecodeError\",\n ...base,\n error: OpcuaError.decodeError({\n nodeId: entry.nodeId,\n cause: error,\n }),\n rawValue: dataValue.value?.value,\n }) as OpcuaSubscription.MonitorSample<Items>,\n value: (value) =>\n ({\n _tag: \"Value\",\n ...base,\n value,\n }) as OpcuaSubscription.MonitorSample<Items>,\n });\n });\n\nconst monitorSampleBase = <Items>(\n entry: WireMonitorEntry<Items>,\n dataValue: DataValue,\n) => ({\n key: entry.key,\n nodeId: entry.nodeId,\n status: normalizeStatusCode(dataValue.statusCode),\n sourceTimestamp:\n entry.timestamps === \"source\" || entry.timestamps === \"both\"\n ? dateTimestamp(dataValue.sourceTimestamp)\n : undefined,\n serverTimestamp:\n entry.timestamps === \"server\" || entry.timestamps === \"both\"\n ? dateTimestamp(dataValue.serverTimestamp)\n : undefined,\n});\n\nconst dateTimestamp = (timestamp: Date | null | undefined) =>\n timestamp instanceof Date ? timestamp : undefined;\n"],"mappings":";;;;;;;AA0BA,MAAa,8BACX,OACA,WACA,qBAEA,OAAO,cAAc;CACnB,MAAM,OAAO,kBAAkB,OAAO,UAAU;AAChD,QAAO,0BAIL;EACA,YAAY,UAAU;EACtB,QAAQ;EACR,QAAQ,MAAM,OACZ,MAAM,IAAI,OACV,UAAU,OACV,WACA,iBACD;EACD,gBAAgB,YACb;GAAE,MAAM;GAAU,GAAGA;GAAM;EAC9B,cAAc,OAAO,YAClB;GACC,MAAM;GACN,GAAGA;GACH,OAAOC,YAAuB;IAC5B,QAAQ,MAAM;IACd,OAAO;IACR,CAAC;GACF,UAAU,UAAU,OAAO;GAC5B;EACH,QAAQ,WACL;GACC,MAAM;GACN,GAAG;GACH;GACD;EACJ,CAAC;EACF;AAEJ,MAAM,qBACJ,OACA,eACI;CACJ,KAAK,MAAM;CACX,QAAQ,MAAM;CACd,QAAQ,oBAAoB,UAAU,WAAW;CACjD,iBACE,MAAM,eAAe,YAAY,MAAM,eAAe,SAClD,cAAc,UAAU,gBAAgB,GACxC;CACN,iBACE,MAAM,eAAe,YAAY,MAAM,eAAe,SAClD,cAAc,UAAU,gBAAgB,GACxC;CACP;AAED,MAAM,iBAAiB,cACrB,qBAAqB,OAAO,YAAY"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { OpcuaSessionCreateError } from "../../OpcuaError.mjs";
|
|
2
|
+
import { Client } from "../../OpcuaClient.mjs";
|
|
3
|
+
import { SessionOptions, SessionService } from "../../OpcuaSession.mjs";
|
|
4
|
+
import { Effect } from "effect";
|
|
5
|
+
import * as effect_Scope6 from "effect/Scope";
|
|
6
|
+
|
|
7
|
+
//#region src/internal/session/make.d.ts
|
|
8
|
+
declare const make: (options?: SessionOptions | undefined) => Effect.Effect<SessionService, OpcuaSessionCreateError, Client | effect_Scope6.Scope>;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { make };
|
|
11
|
+
//# sourceMappingURL=make.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"make.d.mts","names":[],"sources":["../../../src/internal/session/make.ts"],"sourcesContent":[],"mappings":";;;;;;;cAUa,iBAAI,+BAAA,MAAA,CAAA,OAAA,gBAAA,yBAAA,SAAA,aAAA,CAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { sessionCloseError, sessionCreateError } from "../../OpcuaError.mjs";
|
|
2
|
+
import { wireSessionEvents } from "../events/wire.mjs";
|
|
3
|
+
import { EVENT_BUFFER_SIZE } from "../common/constants.mjs";
|
|
4
|
+
import { Client } from "../../OpcuaClient.mjs";
|
|
5
|
+
import { makeSession } from "./service.mjs";
|
|
6
|
+
import { Effect, PubSub } from "effect";
|
|
7
|
+
|
|
8
|
+
//#region src/internal/session/make.ts
|
|
9
|
+
const make = Effect.fnUntraced(function* (options) {
|
|
10
|
+
const client = yield* Client;
|
|
11
|
+
const events = yield* PubSub.sliding({
|
|
12
|
+
capacity: EVENT_BUFFER_SIZE,
|
|
13
|
+
replay: 1
|
|
14
|
+
});
|
|
15
|
+
yield* Effect.addFinalizer(() => PubSub.shutdown(events));
|
|
16
|
+
const raw = yield* Effect.acquireRelease(Effect.tryPromise({
|
|
17
|
+
try: async (signal) => {
|
|
18
|
+
const session = await client.unsafeRawClient.createSession(options?.userIdentity);
|
|
19
|
+
if (signal.aborted) {
|
|
20
|
+
await session.close(true).catch(() => void 0);
|
|
21
|
+
throw new Error("Session creation aborted");
|
|
22
|
+
}
|
|
23
|
+
return session;
|
|
24
|
+
},
|
|
25
|
+
catch: (cause) => sessionCreateError({ cause })
|
|
26
|
+
}).pipe(Effect.withSpan("opcua.session.create", { kind: "client" })), (session) => Effect.tryPromise({
|
|
27
|
+
try: () => session.close(true),
|
|
28
|
+
catch: (cause) => sessionCloseError({ cause })
|
|
29
|
+
}).pipe(Effect.withSpan("opcua.session.close", { kind: "client" }), Effect.ignore));
|
|
30
|
+
yield* wireSessionEvents(raw, events);
|
|
31
|
+
return yield* makeSession(raw, events, { batching: options?.batching });
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
export { make };
|
|
36
|
+
//# sourceMappingURL=make.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"make.mjs","names":["OpcuaClient.Client","OpcuaError.sessionCreateError","OpcuaError.sessionCloseError"],"sources":["../../../src/internal/session/make.ts"],"sourcesContent":["import { Effect, PubSub } from \"effect\";\n\nimport * as OpcuaClient from \"../../OpcuaClient.js\";\nimport * as OpcuaError from \"../../OpcuaError.js\";\nimport type * as OpcuaSession from \"../../OpcuaSession.js\";\nimport { EVENT_BUFFER_SIZE } from \"../common/constants.js\";\nimport type { OpcuaSessionEvent } from \"../events/model.js\";\nimport { wireSessionEvents } from \"../events/wire.js\";\nimport { makeSession } from \"./service.js\";\n\nexport const make = Effect.fnUntraced(function* (\n options?: OpcuaSession.SessionOptions,\n) {\n const client = yield* OpcuaClient.Client;\n const events = yield* PubSub.sliding<OpcuaSessionEvent>({\n capacity: EVENT_BUFFER_SIZE,\n replay: 1,\n });\n yield* Effect.addFinalizer(() => PubSub.shutdown(events));\n\n const raw = yield* Effect.acquireRelease(\n Effect.tryPromise({\n try: async (signal) => {\n const session = await client.unsafeRawClient.createSession(\n options?.userIdentity,\n );\n if (signal.aborted) {\n await session.close(true).catch(() => undefined);\n throw new Error(\"Session creation aborted\");\n }\n return session;\n },\n catch: (cause) => OpcuaError.sessionCreateError({ cause }),\n }).pipe(Effect.withSpan(\"opcua.session.create\", { kind: \"client\" })),\n (session) =>\n Effect.tryPromise({\n try: () => session.close(true),\n catch: (cause) => OpcuaError.sessionCloseError({ cause }),\n }).pipe(\n Effect.withSpan(\"opcua.session.close\", { kind: \"client\" }),\n Effect.ignore,\n ),\n );\n yield* wireSessionEvents(raw, events);\n return yield* makeSession(raw, events, { batching: options?.batching });\n});\n"],"mappings":";;;;;;;;AAUA,MAAa,OAAO,OAAO,WAAW,WACpC,SACA;CACA,MAAM,SAAS,OAAOA;CACtB,MAAM,SAAS,OAAO,OAAO,QAA2B;EACtD,UAAU;EACV,QAAQ;EACT,CAAC;AACF,QAAO,OAAO,mBAAmB,OAAO,SAAS,OAAO,CAAC;CAEzD,MAAM,MAAM,OAAO,OAAO,eACxB,OAAO,WAAW;EAChB,KAAK,OAAO,WAAW;GACrB,MAAM,UAAU,MAAM,OAAO,gBAAgB,cAC3C,SAAS,aACV;AACD,OAAI,OAAO,SAAS;AAClB,UAAM,QAAQ,MAAM,KAAK,CAAC,YAAY,OAAU;AAChD,UAAM,IAAI,MAAM,2BAA2B;;AAE7C,UAAO;;EAET,QAAQ,UAAUC,mBAA8B,EAAE,OAAO,CAAC;EAC3D,CAAC,CAAC,KAAK,OAAO,SAAS,wBAAwB,EAAE,MAAM,UAAU,CAAC,CAAC,GACnE,YACC,OAAO,WAAW;EAChB,WAAW,QAAQ,MAAM,KAAK;EAC9B,QAAQ,UAAUC,kBAA6B,EAAE,OAAO,CAAC;EAC1D,CAAC,CAAC,KACD,OAAO,SAAS,uBAAuB,EAAE,MAAM,UAAU,CAAC,EAC1D,OAAO,OACR,CACJ;AACD,QAAO,kBAAkB,KAAK,OAAO;AACrC,QAAO,OAAO,YAAY,KAAK,QAAQ,EAAE,UAAU,SAAS,UAAU,CAAC;EACvE"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { OpcuaSessionEvent } from "../events/model.mjs";
|
|
2
|
+
import { SessionOptions, SessionService } from "../../OpcuaSession.mjs";
|
|
3
|
+
import { ClientSession } from "node-opcua";
|
|
4
|
+
import { Effect, PubSub, Scope } from "effect";
|
|
5
|
+
|
|
6
|
+
//#region src/internal/session/service.d.ts
|
|
7
|
+
declare const makeSession: (unsafeRaw: ClientSession, events: PubSub.PubSub<OpcuaSessionEvent>, options?: Pick<SessionOptions, "batching">) => Effect.Effect<SessionService, never, Scope.Scope>;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { makeSession };
|
|
10
|
+
//# sourceMappingURL=service.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.mts","names":[],"sources":["../../../src/internal/session/service.ts"],"sourcesContent":[],"mappings":";;;;;;cAuCa,yBACA,uBACH,MAAA,CAAO,OAAO,8BACZ,KAAK,gCACZ,MAAA,CAAO,OAAO,uBAAoC,KAAA,CAAM"}
|