@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,232 @@
|
|
|
1
|
+
import { serviceError } from "../../OpcuaError.mjs";
|
|
2
|
+
import { makeStructureRuntime } from "../structures/runtime.mjs";
|
|
3
|
+
import { readVariable, writeVariable } from "../variable/operations.mjs";
|
|
4
|
+
import { makeVariableDef } from "../../OpcuaVariable.mjs";
|
|
5
|
+
import { DEFAULT_BROWSE_DIRECTION, DEFAULT_BROWSE_INCLUDE_SUBTYPES, DEFAULT_BROWSE_MAX_REFERENCES_PER_NODE, DEFAULT_BROWSE_NODE_CLASS_MASK, DEFAULT_BROWSE_REFERENCE_TYPE_ID, DEFAULT_BROWSE_RESULT_MASK } from "../common/constants.mjs";
|
|
6
|
+
import { callResolvedMethod, resolveMethod } from "../method/operations.mjs";
|
|
7
|
+
import { browseContinuationError, browseOptionsError, browseWithMaxReferences, normalizeBrowseResult } from "../browse/operations.mjs";
|
|
8
|
+
import { makeMetadataService } from "../metadata/service.mjs";
|
|
9
|
+
import { callManyWithState, readManyWithState, writeManyWithState } from "../batch/operations.mjs";
|
|
10
|
+
import { makeSubscriptionRuntime } from "../subscription/runtime.mjs";
|
|
11
|
+
import { readDataTypeDefinition, readManyDataTypeDefinitions } from "../data-types/read.mjs";
|
|
12
|
+
import { OpcuaSession as Session } from "../../OpcuaSession.mjs";
|
|
13
|
+
import { resolveNodeId } from "node-opcua";
|
|
14
|
+
import { Effect, Result, Semaphore, Stream } from "effect";
|
|
15
|
+
|
|
16
|
+
//#region src/internal/session/service.ts
|
|
17
|
+
const makeSession = Effect.fnUntraced(function* (unsafeRaw, events, options) {
|
|
18
|
+
const browseSemaphore = Semaphore.makeUnsafe(1);
|
|
19
|
+
const structureRuntime = makeStructureRuntime(unsafeRaw);
|
|
20
|
+
const metadata = makeMetadataService(unsafeRaw, structureRuntime);
|
|
21
|
+
const state = {
|
|
22
|
+
unsafeRaw,
|
|
23
|
+
metadata,
|
|
24
|
+
structureRuntime,
|
|
25
|
+
batching: options?.batching
|
|
26
|
+
};
|
|
27
|
+
yield* Effect.acquireRelease(Effect.sync(() => {
|
|
28
|
+
const listener = () => {
|
|
29
|
+
Effect.runSync(metadata.invalidate.pipe(Effect.andThen(structureRuntime.invalidate)));
|
|
30
|
+
};
|
|
31
|
+
unsafeRaw.on("session_restored", listener);
|
|
32
|
+
return listener;
|
|
33
|
+
}), (listener) => Effect.sync(() => {
|
|
34
|
+
if ("off" in unsafeRaw && typeof unsafeRaw.off === "function") unsafeRaw.off("session_restored", listener);
|
|
35
|
+
else unsafeRaw.removeListener("session_restored", listener);
|
|
36
|
+
}));
|
|
37
|
+
const read = (def) => Effect.gen(function* () {
|
|
38
|
+
yield* metadata.variable(def);
|
|
39
|
+
return yield* readVariable(unsafeRaw, def, structureRuntime);
|
|
40
|
+
}).pipe(Effect.withSpan("opcua.session.read", {
|
|
41
|
+
attributes: { "opcua.node_id": def.nodeId },
|
|
42
|
+
kind: "client"
|
|
43
|
+
}));
|
|
44
|
+
const write = (def, value) => Effect.gen(function* () {
|
|
45
|
+
const variableMetadata = yield* metadata.variable(def);
|
|
46
|
+
return yield* writeVariable(unsafeRaw, def, variableMetadata, value, structureRuntime);
|
|
47
|
+
}).pipe(Effect.withSpan("opcua.session.write", {
|
|
48
|
+
attributes: { "opcua.node_id": def.nodeId },
|
|
49
|
+
kind: "client"
|
|
50
|
+
}));
|
|
51
|
+
const readMany = (items, options$1) => readManyWithState(state, items, options$1).pipe(Effect.withSpan("opcua.session.readMany", {
|
|
52
|
+
attributes: { "opcua.node_count": Object.keys(items).length },
|
|
53
|
+
kind: "client"
|
|
54
|
+
}));
|
|
55
|
+
const writeMany = (items, options$1) => writeManyWithState(state, items, options$1).pipe(Effect.withSpan("opcua.session.writeMany", {
|
|
56
|
+
attributes: { "opcua.node_count": Object.keys(items).length },
|
|
57
|
+
kind: "client"
|
|
58
|
+
}));
|
|
59
|
+
const makeSubscription = (options$1) => makeSubscriptionRuntime(unsafeRaw, options$1, structureRuntime, (def) => metadata.variable(def));
|
|
60
|
+
const call = (def, input, options$1) => Effect.gen(function* () {
|
|
61
|
+
const methodMetadata = yield* metadata.method(def);
|
|
62
|
+
const method = yield* resolveMethod(def, methodMetadata);
|
|
63
|
+
return yield* callResolvedMethod(unsafeRaw, method, input, structureRuntime, options$1);
|
|
64
|
+
}).pipe(Effect.withSpan("opcua.session.call", {
|
|
65
|
+
attributes: {
|
|
66
|
+
"opcua.object_id": def.objectId,
|
|
67
|
+
"opcua.method_id": def.methodId
|
|
68
|
+
},
|
|
69
|
+
kind: "client"
|
|
70
|
+
}));
|
|
71
|
+
const callMany = (items, options$1) => callManyWithState(state, items, options$1).pipe(Effect.withSpan("opcua.session.callMany", {
|
|
72
|
+
attributes: { "opcua.method_count": Object.keys(items).length },
|
|
73
|
+
kind: "client"
|
|
74
|
+
}));
|
|
75
|
+
const browse = (input) => Effect.gen(function* () {
|
|
76
|
+
const validationError = browseOptionsError(input);
|
|
77
|
+
if (validationError) return yield* Effect.fail(validationError);
|
|
78
|
+
const result = yield* Effect.tryPromise({
|
|
79
|
+
try: () => browseWithMaxReferences(unsafeRaw, {
|
|
80
|
+
nodeId: resolveNodeId(input.nodeId),
|
|
81
|
+
referenceTypeId: resolveNodeId(input.referenceTypeId ?? DEFAULT_BROWSE_REFERENCE_TYPE_ID),
|
|
82
|
+
browseDirection: input.browseDirection ?? DEFAULT_BROWSE_DIRECTION,
|
|
83
|
+
includeSubtypes: input.includeSubtypes ?? DEFAULT_BROWSE_INCLUDE_SUBTYPES,
|
|
84
|
+
nodeClassMask: input.nodeClassMask ?? DEFAULT_BROWSE_NODE_CLASS_MASK,
|
|
85
|
+
resultMask: input.resultMask ?? DEFAULT_BROWSE_RESULT_MASK
|
|
86
|
+
}, input.maxReferencesPerNode ?? DEFAULT_BROWSE_MAX_REFERENCES_PER_NODE),
|
|
87
|
+
catch: (cause) => serviceError({
|
|
88
|
+
operation: "browse",
|
|
89
|
+
nodeId: input.nodeId,
|
|
90
|
+
cause
|
|
91
|
+
})
|
|
92
|
+
}).pipe(browseSemaphore.withPermits(1));
|
|
93
|
+
return normalizeBrowseResult(input.nodeId, result, input.includeRaw ?? false);
|
|
94
|
+
}).pipe(Effect.withSpan("opcua.session.browse", {
|
|
95
|
+
attributes: {
|
|
96
|
+
"opcua.node_id": input.nodeId,
|
|
97
|
+
"opcua.max_references_per_node": input.maxReferencesPerNode ?? DEFAULT_BROWSE_MAX_REFERENCES_PER_NODE
|
|
98
|
+
},
|
|
99
|
+
kind: "client"
|
|
100
|
+
}));
|
|
101
|
+
const browseNext = (continuation) => Effect.gen(function* () {
|
|
102
|
+
const validationError = browseContinuationError("browseNext", continuation);
|
|
103
|
+
if (validationError) return yield* Effect.fail(validationError);
|
|
104
|
+
const result = yield* Effect.tryPromise({
|
|
105
|
+
try: () => unsafeRaw.browseNext(continuation.unsafeRaw, false),
|
|
106
|
+
catch: (cause) => serviceError({
|
|
107
|
+
operation: "browseNext",
|
|
108
|
+
nodeId: continuation.nodeId,
|
|
109
|
+
cause
|
|
110
|
+
})
|
|
111
|
+
});
|
|
112
|
+
return normalizeBrowseResult(continuation.nodeId, result, continuation.includeRaw ?? false);
|
|
113
|
+
}).pipe(Effect.withSpan("opcua.session.browseNext", {
|
|
114
|
+
attributes: { "opcua.node_id": continuation.nodeId },
|
|
115
|
+
kind: "client"
|
|
116
|
+
}));
|
|
117
|
+
const releaseBrowseContinuation = (continuation) => Effect.gen(function* () {
|
|
118
|
+
const validationError = browseContinuationError("releaseBrowseContinuation", continuation);
|
|
119
|
+
if (validationError) return yield* Effect.fail(validationError);
|
|
120
|
+
yield* Effect.tryPromise({
|
|
121
|
+
try: () => unsafeRaw.browseNext(continuation.unsafeRaw, true),
|
|
122
|
+
catch: (cause) => serviceError({
|
|
123
|
+
operation: "releaseBrowseContinuation",
|
|
124
|
+
nodeId: continuation.nodeId,
|
|
125
|
+
cause
|
|
126
|
+
})
|
|
127
|
+
});
|
|
128
|
+
}).pipe(Effect.withSpan("opcua.session.releaseBrowseContinuation", {
|
|
129
|
+
attributes: { "opcua.node_id": continuation.nodeId },
|
|
130
|
+
kind: "client"
|
|
131
|
+
}));
|
|
132
|
+
const browseChildren = (nodeId, options$1) => Effect.gen(function* () {
|
|
133
|
+
const mode = options$1?.mode ?? "all";
|
|
134
|
+
const first = yield* browse({
|
|
135
|
+
nodeId,
|
|
136
|
+
referenceTypeId: options$1?.referenceTypeId ?? DEFAULT_BROWSE_REFERENCE_TYPE_ID,
|
|
137
|
+
includeSubtypes: options$1?.includeSubtypes ?? DEFAULT_BROWSE_INCLUDE_SUBTYPES,
|
|
138
|
+
nodeClassMask: options$1?.nodeClassMask ?? DEFAULT_BROWSE_NODE_CLASS_MASK,
|
|
139
|
+
maxReferencesPerNode: options$1?.maxReferencesPerNode ?? DEFAULT_BROWSE_MAX_REFERENCES_PER_NODE,
|
|
140
|
+
includeRaw: options$1?.includeRaw
|
|
141
|
+
});
|
|
142
|
+
if (first._tag === "NonGoodStatus") return first;
|
|
143
|
+
if (mode === "page") return {
|
|
144
|
+
_tag: "Browsed",
|
|
145
|
+
nodeId,
|
|
146
|
+
status: first.status,
|
|
147
|
+
references: first.references,
|
|
148
|
+
continuation: first.continuation
|
|
149
|
+
};
|
|
150
|
+
const references = [...first.references];
|
|
151
|
+
let continuation = first.continuation;
|
|
152
|
+
while (continuation) {
|
|
153
|
+
const next = yield* browseNext({
|
|
154
|
+
...continuation,
|
|
155
|
+
includeRaw: options$1?.includeRaw
|
|
156
|
+
});
|
|
157
|
+
if (next._tag === "NonGoodStatus") return next;
|
|
158
|
+
references.push(...next.references);
|
|
159
|
+
continuation = next.continuation;
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
_tag: "Browsed",
|
|
163
|
+
nodeId,
|
|
164
|
+
status: first.status,
|
|
165
|
+
references
|
|
166
|
+
};
|
|
167
|
+
}).pipe(Effect.withSpan("opcua.session.browseChildren", {
|
|
168
|
+
attributes: {
|
|
169
|
+
"opcua.node_id": nodeId,
|
|
170
|
+
"opcua.browse_mode": options$1?.mode ?? "all"
|
|
171
|
+
},
|
|
172
|
+
kind: "client"
|
|
173
|
+
}));
|
|
174
|
+
const readNamespaceArray = () => metadata.namespaceArray();
|
|
175
|
+
const readNodeMetadata = (nodeId) => metadata.node(nodeId);
|
|
176
|
+
const readManyNodeMetadata = (nodeIds) => metadata.nodes(nodeIds);
|
|
177
|
+
const readDataTypeDefinition$1 = (dataTypeNodeId) => readDataTypeDefinition(unsafeRaw, metadata, dataTypeNodeId);
|
|
178
|
+
const readManyDataTypeDefinitions$1 = (dataTypeNodeIds) => readManyDataTypeDefinitions(unsafeRaw, metadata, dataTypeNodeIds);
|
|
179
|
+
const isValueReadable = (nodeMetadata) => nodeMetadata.accessLevel?.readable === true && nodeMetadata.userAccessLevel?.readable !== false;
|
|
180
|
+
const inspectValue = (nodeId, nodeMetadata) => isValueReadable(nodeMetadata) ? Effect.map(Effect.result(read(makeVariableDef({
|
|
181
|
+
nodeId,
|
|
182
|
+
access: "read"
|
|
183
|
+
}))), (result) => Result.isSuccess(result) ? result.success : {
|
|
184
|
+
_tag: "ReadFailed",
|
|
185
|
+
nodeId,
|
|
186
|
+
error: result.failure
|
|
187
|
+
}) : Effect.succeed({
|
|
188
|
+
_tag: "NotReadable",
|
|
189
|
+
nodeId
|
|
190
|
+
});
|
|
191
|
+
const inspectNode = (nodeId, options$1) => Effect.gen(function* () {
|
|
192
|
+
const nodeMetadata = yield* metadata.node(nodeId);
|
|
193
|
+
return {
|
|
194
|
+
nodeId,
|
|
195
|
+
metadata: nodeMetadata,
|
|
196
|
+
value: options$1?.value === true ? yield* inspectValue(nodeId, nodeMetadata) : void 0,
|
|
197
|
+
dataTypeDefinition: options$1?.dataTypeDefinition === true && nodeMetadata.dataType !== void 0 ? yield* readDataTypeDefinition(unsafeRaw, metadata, nodeMetadata.dataType) : void 0
|
|
198
|
+
};
|
|
199
|
+
}).pipe(Effect.withSpan("opcua.session.inspectNode", {
|
|
200
|
+
attributes: {
|
|
201
|
+
"opcua.node_id": nodeId,
|
|
202
|
+
"opcua.inspect_value": options$1?.value === true,
|
|
203
|
+
"opcua.inspect_data_type_definition": options$1?.dataTypeDefinition === true
|
|
204
|
+
},
|
|
205
|
+
kind: "client"
|
|
206
|
+
}));
|
|
207
|
+
return Session.of({
|
|
208
|
+
read,
|
|
209
|
+
write,
|
|
210
|
+
readMany,
|
|
211
|
+
writeMany,
|
|
212
|
+
makeSubscription,
|
|
213
|
+
call,
|
|
214
|
+
callMany,
|
|
215
|
+
browse,
|
|
216
|
+
browseNext,
|
|
217
|
+
releaseBrowseContinuation,
|
|
218
|
+
browseChildren,
|
|
219
|
+
readNamespaceArray,
|
|
220
|
+
readNodeMetadata,
|
|
221
|
+
readManyNodeMetadata,
|
|
222
|
+
readDataTypeDefinition: readDataTypeDefinition$1,
|
|
223
|
+
readManyDataTypeDefinitions: readManyDataTypeDefinitions$1,
|
|
224
|
+
inspectNode,
|
|
225
|
+
events: Stream.fromPubSub(events),
|
|
226
|
+
unsafeRaw
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
//#endregion
|
|
231
|
+
export { makeSession };
|
|
232
|
+
//# sourceMappingURL=service.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.mjs","names":["makeSession: (\n unsafeRaw: ClientSession,\n events: PubSub.PubSub<OpcuaSessionEvent>,\n options?: Pick<OpcuaSession.SessionOptions, \"batching\">,\n) => Effect.Effect<OpcuaSession.SessionService, never, Scope.Scope>","state: SessionOperationsState","read: OpcuaSession.SessionService[\"read\"]","VariableOperations.readVariable","write: OpcuaSession.SessionService[\"write\"]","VariableOperations.writeVariable","readMany: OpcuaSession.SessionService[\"readMany\"]","options","writeMany: OpcuaSession.SessionService[\"writeMany\"]","makeSubscription: OpcuaSession.SessionService[\"makeSubscription\"]","call: OpcuaSession.SessionService[\"call\"]","MethodOperations.resolveMethod","MethodOperations.callResolvedMethod","callMany: OpcuaSession.SessionService[\"callMany\"]","browse: OpcuaSession.SessionService[\"browse\"]","OpcuaError.serviceError","browseNext: OpcuaSession.SessionService[\"browseNext\"]","releaseBrowseContinuation: OpcuaSession.SessionService[\"releaseBrowseContinuation\"]","browseChildren: OpcuaSession.SessionService[\"browseChildren\"]","readNamespaceArray: OpcuaSession.SessionService[\"readNamespaceArray\"]","readNodeMetadata: OpcuaSession.SessionService[\"readNodeMetadata\"]","readManyNodeMetadata: OpcuaSession.SessionService[\"readManyNodeMetadata\"]","readDataTypeDefinition: OpcuaSession.SessionService[\"readDataTypeDefinition\"]","readDataTypeDefinitionImpl","readManyDataTypeDefinitions: OpcuaSession.SessionService[\"readManyDataTypeDefinitions\"]","readManyDataTypeDefinitionsImpl","OpcuaVariable.makeVariableDef","inspectNode: OpcuaSession.SessionService[\"inspectNode\"]"],"sources":["../../../src/internal/session/service.ts"],"sourcesContent":["import { resolveNodeId, type ClientSession } from \"node-opcua\";\nimport { Effect, PubSub, Result, Scope, Semaphore, Stream } from \"effect\";\n\nimport * as OpcuaError from \"../../OpcuaError.js\";\nimport * as OpcuaSession from \"../../OpcuaSession.js\";\nimport * as OpcuaVariable from \"../../OpcuaVariable.js\";\nimport * as MethodOperations from \"../method/operations.js\";\nimport * as VariableOperations from \"../variable/operations.js\";\n\nimport {\n browseContinuationError,\n browseOptionsError,\n browseWithMaxReferences,\n normalizeBrowseResult,\n} from \"../browse/operations.js\";\nimport { type OpcuaSessionEvent } from \"../events/model.js\";\nimport { makeMetadataService } from \"../metadata/service.js\";\nimport { makeStructureRuntime } from \"../structures/runtime.js\";\nimport {\n callManyWithState,\n readManyWithState,\n writeManyWithState,\n type SessionOperationsState,\n} from \"../batch/operations.js\";\nimport { makeSubscriptionRuntime } from \"../subscription/runtime.js\";\nimport {\n readDataTypeDefinition as readDataTypeDefinitionImpl,\n readManyDataTypeDefinitions as readManyDataTypeDefinitionsImpl,\n} from \"../data-types/read.js\";\n\nimport {\n DEFAULT_BROWSE_DIRECTION,\n DEFAULT_BROWSE_INCLUDE_SUBTYPES,\n DEFAULT_BROWSE_MAX_REFERENCES_PER_NODE,\n DEFAULT_BROWSE_NODE_CLASS_MASK,\n DEFAULT_BROWSE_REFERENCE_TYPE_ID,\n DEFAULT_BROWSE_RESULT_MASK,\n} from \"../common/constants.js\";\n\nexport const makeSession: (\n unsafeRaw: ClientSession,\n events: PubSub.PubSub<OpcuaSessionEvent>,\n options?: Pick<OpcuaSession.SessionOptions, \"batching\">,\n) => Effect.Effect<OpcuaSession.SessionService, never, Scope.Scope> =\n Effect.fnUntraced(function* (unsafeRaw, events, options) {\n const browseSemaphore = Semaphore.makeUnsafe(1);\n const structureRuntime = makeStructureRuntime(unsafeRaw);\n const metadata = makeMetadataService(unsafeRaw, structureRuntime);\n const state: SessionOperationsState = {\n unsafeRaw,\n metadata,\n structureRuntime,\n batching: options?.batching,\n };\n yield* Effect.acquireRelease(\n Effect.sync(() => {\n const listener = () => {\n Effect.runSync(\n metadata.invalidate.pipe(\n Effect.andThen(structureRuntime.invalidate),\n ),\n );\n };\n unsafeRaw.on(\"session_restored\", listener);\n return listener;\n }),\n (listener) =>\n Effect.sync(() => {\n if (\"off\" in unsafeRaw && typeof unsafeRaw.off === \"function\") {\n unsafeRaw.off(\"session_restored\", listener);\n } else {\n unsafeRaw.removeListener(\"session_restored\", listener);\n }\n }),\n );\n\n const read: OpcuaSession.SessionService[\"read\"] = (def) =>\n Effect.gen(function* () {\n yield* metadata.variable(def);\n const result = yield* VariableOperations.readVariable(\n unsafeRaw,\n def,\n structureRuntime,\n );\n return result as OpcuaVariable.ReadResult<\n OpcuaVariable.ValueOfVariableDef<typeof def>,\n OpcuaVariable.NodeIdOfVariableDef<typeof def>\n >;\n }).pipe(\n Effect.withSpan(\"opcua.session.read\", {\n attributes: { \"opcua.node_id\": def.nodeId },\n kind: \"client\",\n }),\n );\n\n const write: OpcuaSession.SessionService[\"write\"] = (def, value) =>\n Effect.gen(function* () {\n const variableMetadata = yield* metadata.variable(def);\n const result = yield* VariableOperations.writeVariable(\n unsafeRaw,\n def,\n variableMetadata,\n value,\n structureRuntime,\n );\n return result as OpcuaVariable.WriteResult<\n OpcuaVariable.NodeIdOfVariableDef<typeof def>\n >;\n }).pipe(\n Effect.withSpan(\"opcua.session.write\", {\n attributes: { \"opcua.node_id\": def.nodeId },\n kind: \"client\",\n }),\n );\n\n const readMany: OpcuaSession.SessionService[\"readMany\"] = (\n items,\n options,\n ) =>\n readManyWithState(state, items, options).pipe(\n Effect.withSpan(\"opcua.session.readMany\", {\n attributes: { \"opcua.node_count\": Object.keys(items).length },\n kind: \"client\",\n }),\n );\n\n const writeMany: OpcuaSession.SessionService[\"writeMany\"] = (\n items,\n options,\n ) =>\n writeManyWithState(state, items, options).pipe(\n Effect.withSpan(\"opcua.session.writeMany\", {\n attributes: { \"opcua.node_count\": Object.keys(items).length },\n kind: \"client\",\n }),\n );\n\n const makeSubscription: OpcuaSession.SessionService[\"makeSubscription\"] = (\n options,\n ) =>\n makeSubscriptionRuntime(unsafeRaw, options, structureRuntime, (def) =>\n metadata.variable(def),\n );\n\n const call: OpcuaSession.SessionService[\"call\"] = (def, input, options) =>\n Effect.gen(function* () {\n const methodMetadata = yield* metadata.method(def);\n const method = yield* MethodOperations.resolveMethod(\n def,\n methodMetadata,\n );\n return yield* MethodOperations.callResolvedMethod(\n unsafeRaw,\n method,\n input,\n structureRuntime,\n options,\n );\n }).pipe(\n Effect.withSpan(\"opcua.session.call\", {\n attributes: {\n \"opcua.object_id\": def.objectId,\n \"opcua.method_id\": def.methodId,\n },\n kind: \"client\",\n }),\n );\n\n const callMany: OpcuaSession.SessionService[\"callMany\"] = (\n items,\n options,\n ) =>\n callManyWithState(state, items, options).pipe(\n Effect.withSpan(\"opcua.session.callMany\", {\n attributes: { \"opcua.method_count\": Object.keys(items).length },\n kind: \"client\",\n }),\n );\n\n const browse: OpcuaSession.SessionService[\"browse\"] = (input) =>\n Effect.gen(function* () {\n const validationError = browseOptionsError(input);\n if (validationError) return yield* Effect.fail(validationError);\n\n const result = yield* Effect.tryPromise({\n try: () =>\n browseWithMaxReferences(\n unsafeRaw,\n {\n nodeId: resolveNodeId(input.nodeId),\n referenceTypeId: resolveNodeId(\n input.referenceTypeId ?? DEFAULT_BROWSE_REFERENCE_TYPE_ID,\n ),\n browseDirection:\n input.browseDirection ?? DEFAULT_BROWSE_DIRECTION,\n includeSubtypes:\n input.includeSubtypes ?? DEFAULT_BROWSE_INCLUDE_SUBTYPES,\n nodeClassMask:\n input.nodeClassMask ?? DEFAULT_BROWSE_NODE_CLASS_MASK,\n resultMask: input.resultMask ?? DEFAULT_BROWSE_RESULT_MASK,\n },\n input.maxReferencesPerNode ??\n DEFAULT_BROWSE_MAX_REFERENCES_PER_NODE,\n ),\n catch: (cause) =>\n OpcuaError.serviceError({\n operation: \"browse\",\n nodeId: input.nodeId,\n cause,\n }),\n }).pipe(browseSemaphore.withPermits(1));\n\n return normalizeBrowseResult(\n input.nodeId,\n result,\n input.includeRaw ?? false,\n );\n }).pipe(\n Effect.withSpan(\"opcua.session.browse\", {\n attributes: {\n \"opcua.node_id\": input.nodeId,\n \"opcua.max_references_per_node\":\n input.maxReferencesPerNode ??\n DEFAULT_BROWSE_MAX_REFERENCES_PER_NODE,\n },\n kind: \"client\",\n }),\n );\n\n const browseNext: OpcuaSession.SessionService[\"browseNext\"] = (\n continuation,\n ) =>\n Effect.gen(function* () {\n const validationError = browseContinuationError(\n \"browseNext\",\n continuation,\n );\n if (validationError) return yield* Effect.fail(validationError);\n\n const result = yield* Effect.tryPromise({\n try: () => unsafeRaw.browseNext(continuation.unsafeRaw, false),\n catch: (cause) =>\n OpcuaError.serviceError({\n operation: \"browseNext\",\n nodeId: continuation.nodeId,\n cause,\n }),\n });\n\n return normalizeBrowseResult(\n continuation.nodeId,\n result,\n continuation.includeRaw ?? false,\n );\n }).pipe(\n Effect.withSpan(\"opcua.session.browseNext\", {\n attributes: { \"opcua.node_id\": continuation.nodeId },\n kind: \"client\",\n }),\n );\n\n const releaseBrowseContinuation: OpcuaSession.SessionService[\"releaseBrowseContinuation\"] =\n (continuation) =>\n Effect.gen(function* () {\n const validationError = browseContinuationError(\n \"releaseBrowseContinuation\",\n continuation,\n );\n if (validationError) return yield* Effect.fail(validationError);\n\n yield* Effect.tryPromise({\n try: () => unsafeRaw.browseNext(continuation.unsafeRaw, true),\n catch: (cause) =>\n OpcuaError.serviceError({\n operation: \"releaseBrowseContinuation\",\n nodeId: continuation.nodeId,\n cause,\n }),\n });\n }).pipe(\n Effect.withSpan(\"opcua.session.releaseBrowseContinuation\", {\n attributes: { \"opcua.node_id\": continuation.nodeId },\n kind: \"client\",\n }),\n );\n\n const browseChildren: OpcuaSession.SessionService[\"browseChildren\"] = (\n nodeId,\n options,\n ) =>\n Effect.gen(function* () {\n const mode = options?.mode ?? \"all\";\n const first = yield* browse({\n nodeId,\n referenceTypeId:\n options?.referenceTypeId ?? DEFAULT_BROWSE_REFERENCE_TYPE_ID,\n includeSubtypes:\n options?.includeSubtypes ?? DEFAULT_BROWSE_INCLUDE_SUBTYPES,\n nodeClassMask:\n options?.nodeClassMask ?? DEFAULT_BROWSE_NODE_CLASS_MASK,\n maxReferencesPerNode:\n options?.maxReferencesPerNode ??\n DEFAULT_BROWSE_MAX_REFERENCES_PER_NODE,\n includeRaw: options?.includeRaw,\n });\n if (first._tag === \"NonGoodStatus\") return first;\n if (mode === \"page\") {\n return {\n _tag: \"Browsed\" as const,\n nodeId,\n status: first.status,\n references: first.references,\n continuation: first.continuation,\n };\n }\n\n const references = [...first.references];\n let continuation = first.continuation;\n while (continuation) {\n const next = yield* browseNext({\n ...continuation,\n includeRaw: options?.includeRaw,\n });\n if (next._tag === \"NonGoodStatus\") return next;\n references.push(...next.references);\n continuation = next.continuation;\n }\n return {\n _tag: \"Browsed\" as const,\n nodeId,\n status: first.status,\n references,\n };\n }).pipe(\n Effect.withSpan(\"opcua.session.browseChildren\", {\n attributes: {\n \"opcua.node_id\": nodeId,\n \"opcua.browse_mode\": options?.mode ?? \"all\",\n },\n kind: \"client\",\n }),\n );\n\n const readNamespaceArray: OpcuaSession.SessionService[\"readNamespaceArray\"] =\n () => metadata.namespaceArray();\n\n const readNodeMetadata: OpcuaSession.SessionService[\"readNodeMetadata\"] = (\n nodeId,\n ) => metadata.node(nodeId);\n\n const readManyNodeMetadata: OpcuaSession.SessionService[\"readManyNodeMetadata\"] =\n (nodeIds) => metadata.nodes(nodeIds);\n\n const readDataTypeDefinition: OpcuaSession.SessionService[\"readDataTypeDefinition\"] =\n (dataTypeNodeId) =>\n readDataTypeDefinitionImpl(unsafeRaw, metadata, dataTypeNodeId);\n\n const readManyDataTypeDefinitions: OpcuaSession.SessionService[\"readManyDataTypeDefinitions\"] =\n (dataTypeNodeIds) =>\n readManyDataTypeDefinitionsImpl(unsafeRaw, metadata, dataTypeNodeIds);\n\n const isValueReadable = (nodeMetadata: OpcuaSession.OpcuaNodeMetadata) =>\n nodeMetadata.accessLevel?.readable === true &&\n nodeMetadata.userAccessLevel?.readable !== false;\n\n const inspectValue = (\n nodeId: string,\n nodeMetadata: OpcuaSession.OpcuaNodeMetadata,\n ): Effect.Effect<OpcuaSession.OpcuaInspectValueResult> =>\n isValueReadable(nodeMetadata)\n ? Effect.map(\n Effect.result(\n read(OpcuaVariable.makeVariableDef({ nodeId, access: \"read\" })),\n ),\n (result) =>\n Result.isSuccess(result)\n ? result.success\n : {\n _tag: \"ReadFailed\" as const,\n nodeId,\n error: result.failure,\n },\n )\n : Effect.succeed({ _tag: \"NotReadable\" as const, nodeId });\n\n const inspectNode: OpcuaSession.SessionService[\"inspectNode\"] = (\n nodeId,\n options,\n ) =>\n Effect.gen(function* () {\n const nodeMetadata = yield* metadata.node(nodeId);\n const value =\n options?.value === true\n ? yield* inspectValue(nodeId, nodeMetadata)\n : undefined;\n const dataTypeDefinition =\n options?.dataTypeDefinition === true &&\n nodeMetadata.dataType !== undefined\n ? yield* readDataTypeDefinitionImpl(\n unsafeRaw,\n metadata,\n nodeMetadata.dataType,\n )\n : undefined;\n return { nodeId, metadata: nodeMetadata, value, dataTypeDefinition };\n }).pipe(\n Effect.withSpan(\"opcua.session.inspectNode\", {\n attributes: {\n \"opcua.node_id\": nodeId,\n \"opcua.inspect_value\": options?.value === true,\n \"opcua.inspect_data_type_definition\":\n options?.dataTypeDefinition === true,\n },\n kind: \"client\",\n }),\n );\n\n return OpcuaSession.Session.of({\n read,\n write,\n readMany,\n writeMany,\n makeSubscription,\n call,\n callMany,\n browse,\n browseNext,\n releaseBrowseContinuation,\n browseChildren,\n readNamespaceArray,\n readNodeMetadata,\n readManyNodeMetadata,\n readDataTypeDefinition,\n readManyDataTypeDefinitions,\n inspectNode,\n events: Stream.fromPubSub(events),\n unsafeRaw,\n });\n });\n"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ExtensionObject } from "node-opcua";
|
|
2
|
+
|
|
3
|
+
//#region src/internal/structures/adapter.d.ts
|
|
4
|
+
type StructureBody = Readonly<Record<string, unknown>>;
|
|
5
|
+
declare const isNodeOpcuaExtensionObject: (value: unknown) => value is ExtensionObject;
|
|
6
|
+
declare const extensionObjectTypeName: (value: ExtensionObject) => string | undefined;
|
|
7
|
+
declare const structureBodyFromExtensionObject: (value: unknown) => StructureBody;
|
|
8
|
+
declare const extensionObjectBody: (value: ExtensionObject) => StructureBody;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { StructureBody, extensionObjectBody, extensionObjectTypeName, isNodeOpcuaExtensionObject, structureBodyFromExtensionObject };
|
|
11
|
+
//# sourceMappingURL=adapter.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.mts","names":[],"sources":["../../../src/internal/structures/adapter.ts"],"sourcesContent":[],"mappings":";;;KAIY,aAAA,GAAgB,SAAS;cAExB,yDAED;AAJA,cAMC,uBANe,EAAA,CAAA,KAAQ,EAO3B,eAP2B,EAAA,GAAA,MAAA,GAAA,SAAA;AAEvB,cAWA,gCATD,EAAA,CAAA,KAAA,EAAmD,OAAA,EAAA,GAW5D,aAX4D;AAElD,cAgBA,mBAXZ,EAAA,CAJQ,KAAA,EAekC,eAfnB,EAAA,GAeqC,aAfrC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { isPlainRecord } from "../common/predicates.mjs";
|
|
2
|
+
import { ExtensionObject } from "node-opcua";
|
|
3
|
+
|
|
4
|
+
//#region src/internal/structures/adapter.ts
|
|
5
|
+
const isNodeOpcuaExtensionObject = (value) => value instanceof ExtensionObject;
|
|
6
|
+
const extensionObjectTypeName = (value) => {
|
|
7
|
+
const name = value.constructor?.name;
|
|
8
|
+
return name && name !== "ExtensionObject" ? name : void 0;
|
|
9
|
+
};
|
|
10
|
+
const structureBodyFromExtensionObject = (value) => {
|
|
11
|
+
if (!isNodeOpcuaExtensionObject(value)) throw new TypeError("Expected node-opcua ExtensionObject");
|
|
12
|
+
return extensionObjectBody(value);
|
|
13
|
+
};
|
|
14
|
+
const extensionObjectBody = (value) => {
|
|
15
|
+
const json = extensionObjectJson(value);
|
|
16
|
+
const entries = Object.entries(value).filter(([key]) => isStructureDataKey(key));
|
|
17
|
+
if (json && (Object.keys(json).length > 0 || entries.length === 0)) return json;
|
|
18
|
+
if (entries.length > 0) return Object.fromEntries(entries);
|
|
19
|
+
throw new TypeError(`Could not extract ExtensionObject body${extensionObjectNameSuffix(value)}`);
|
|
20
|
+
};
|
|
21
|
+
const extensionObjectJson = (value) => {
|
|
22
|
+
const toJSON = value.toJSON;
|
|
23
|
+
if (typeof toJSON !== "function") return void 0;
|
|
24
|
+
const json = toJSON.call(value);
|
|
25
|
+
if (json === void 0 || json === null) return void 0;
|
|
26
|
+
if (isPlainRecord(json)) return json;
|
|
27
|
+
throw new TypeError(`ExtensionObject toJSON() must return a plain object${extensionObjectNameSuffix(value)}`);
|
|
28
|
+
};
|
|
29
|
+
const extensionObjectNameSuffix = (value) => {
|
|
30
|
+
const name = extensionObjectTypeName(value);
|
|
31
|
+
return name ? ` for ${name}` : "";
|
|
32
|
+
};
|
|
33
|
+
const isStructureDataKey = (key) => !key.startsWith("_") && key !== "schema" && key !== "encode" && key !== "decode" && key !== "binaryStoreSize" && key !== "constructor";
|
|
34
|
+
|
|
35
|
+
//#endregion
|
|
36
|
+
export { extensionObjectBody, extensionObjectTypeName, isNodeOpcuaExtensionObject, structureBodyFromExtensionObject };
|
|
37
|
+
//# sourceMappingURL=adapter.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.mjs","names":[],"sources":["../../../src/internal/structures/adapter.ts"],"sourcesContent":["import { ExtensionObject } from \"node-opcua\";\n\nimport { isPlainRecord } from \"../common/predicates.js\";\n\nexport type StructureBody = Readonly<Record<string, unknown>>;\n\nexport const isNodeOpcuaExtensionObject = (\n value: unknown,\n): value is ExtensionObject => value instanceof ExtensionObject;\n\nexport const extensionObjectTypeName = (\n value: ExtensionObject,\n): string | undefined => {\n const name = value.constructor?.name;\n return name && name !== \"ExtensionObject\" ? name : undefined;\n};\n\nexport const structureBodyFromExtensionObject = (\n value: unknown,\n): StructureBody => {\n if (!isNodeOpcuaExtensionObject(value)) {\n throw new TypeError(\"Expected node-opcua ExtensionObject\");\n }\n return extensionObjectBody(value);\n};\n\nexport const extensionObjectBody = (value: ExtensionObject): StructureBody => {\n const json = extensionObjectJson(value);\n const entries = Object.entries(\n value as unknown as Record<string, unknown>,\n ).filter(([key]) => isStructureDataKey(key));\n\n if (json && (Object.keys(json).length > 0 || entries.length === 0)) {\n return json;\n }\n if (entries.length > 0) return Object.fromEntries(entries);\n\n throw new TypeError(\n `Could not extract ExtensionObject body${extensionObjectNameSuffix(value)}`,\n );\n};\n\nconst extensionObjectJson = (\n value: ExtensionObject,\n): StructureBody | undefined => {\n const toJSON = (value as { readonly toJSON?: unknown }).toJSON;\n if (typeof toJSON !== \"function\") return undefined;\n\n const json = toJSON.call(value);\n if (json === undefined || json === null) return undefined;\n if (isPlainRecord(json)) return json;\n\n throw new TypeError(\n `ExtensionObject toJSON() must return a plain object${extensionObjectNameSuffix(value)}`,\n );\n};\n\nconst extensionObjectNameSuffix = (value: ExtensionObject) => {\n const name = extensionObjectTypeName(value);\n return name ? ` for ${name}` : \"\";\n};\n\nconst isStructureDataKey = (key: string) =>\n !key.startsWith(\"_\") &&\n key !== \"schema\" &&\n key !== \"encode\" &&\n key !== \"decode\" &&\n key !== \"binaryStoreSize\" &&\n key !== \"constructor\";\n"],"mappings":";;;;AAMA,MAAa,8BACX,UAC6B,iBAAiB;AAEhD,MAAa,2BACX,UACuB;CACvB,MAAM,OAAO,MAAM,aAAa;AAChC,QAAO,QAAQ,SAAS,oBAAoB,OAAO;;AAGrD,MAAa,oCACX,UACkB;AAClB,KAAI,CAAC,2BAA2B,MAAM,CACpC,OAAM,IAAI,UAAU,sCAAsC;AAE5D,QAAO,oBAAoB,MAAM;;AAGnC,MAAa,uBAAuB,UAA0C;CAC5E,MAAM,OAAO,oBAAoB,MAAM;CACvC,MAAM,UAAU,OAAO,QACrB,MACD,CAAC,QAAQ,CAAC,SAAS,mBAAmB,IAAI,CAAC;AAE5C,KAAI,SAAS,OAAO,KAAK,KAAK,CAAC,SAAS,KAAK,QAAQ,WAAW,GAC9D,QAAO;AAET,KAAI,QAAQ,SAAS,EAAG,QAAO,OAAO,YAAY,QAAQ;AAE1D,OAAM,IAAI,UACR,yCAAyC,0BAA0B,MAAM,GAC1E;;AAGH,MAAM,uBACJ,UAC8B;CAC9B,MAAM,SAAU,MAAwC;AACxD,KAAI,OAAO,WAAW,WAAY,QAAO;CAEzC,MAAM,OAAO,OAAO,KAAK,MAAM;AAC/B,KAAI,SAAS,UAAa,SAAS,KAAM,QAAO;AAChD,KAAI,cAAc,KAAK,CAAE,QAAO;AAEhC,OAAM,IAAI,UACR,sDAAsD,0BAA0B,MAAM,GACvF;;AAGH,MAAM,6BAA6B,UAA2B;CAC5D,MAAM,OAAO,wBAAwB,MAAM;AAC3C,QAAO,OAAO,QAAQ,SAAS;;AAGjC,MAAM,sBAAsB,QAC1B,CAAC,IAAI,WAAW,IAAI,IACpB,QAAQ,YACR,QAAQ,YACR,QAAQ,YACR,QAAQ,qBACR,QAAQ"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { NodeIdString } from "../../OpcuaVariable.mjs";
|
|
2
|
+
import "../common/node-id.mjs";
|
|
3
|
+
import { Schema } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/internal/structures/model.d.ts
|
|
6
|
+
type StructureDef<A> = {
|
|
7
|
+
readonly _tag: "Structure";
|
|
8
|
+
readonly name: string;
|
|
9
|
+
readonly dataTypeId: NodeIdString;
|
|
10
|
+
readonly schema: Schema.Codec<unknown, A, never, never>;
|
|
11
|
+
};
|
|
12
|
+
type StructureArrayDef<A> = {
|
|
13
|
+
readonly _tag: "StructureArray";
|
|
14
|
+
readonly item: StructureDef<A>;
|
|
15
|
+
};
|
|
16
|
+
type AnyStructureDef = StructureDef<unknown> | StructureArrayDef<unknown>;
|
|
17
|
+
declare const isStructureDef: (value: unknown) => value is StructureDef<unknown>;
|
|
18
|
+
declare const isStructureArrayDef: (value: unknown) => value is StructureArrayDef<unknown>;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { AnyStructureDef, StructureArrayDef, StructureDef, isStructureArrayDef, isStructureDef };
|
|
21
|
+
//# sourceMappingURL=model.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.mts","names":[],"sources":["../../../src/internal/structures/model.ts"],"sourcesContent":[],"mappings":";;;;;KAIY;;;EAAA,SAAA,UAAY,EAGD,YAHC;EAGD,SAAA,MAAA,EACJ,MAAA,CAAO,KADH,CAAA,OAAA,EACkB,CADlB,EAAA,KAAA,EAAA,KAAA,CAAA;CACkB;AAAtB,KAGP,iBAHc,CAAA,CAAA,CAAA,GAAA;EAAK,SAAA,IAAA,EAAA,gBAAA;EAGnB,SAAA,IAAA,EAEK,YAFY,CAEC,CAFD,CAAA;AAK7B,CAAA;AAIa,KAJD,eAAA,GACR,YAKQ,CAAA,OAAY,CAAA,GAJpB,iBAIoB,CAAA,OAAA,CAAA;AAOX,cATA,cAgBV,EAAA,CAAA,KALS,EAAA,OAAA,EAAA,GAAiB,KAAA,IATjB,YASiB,CAAA,OAAA,CAAA;cAFhB,kDAED"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
//#region src/internal/structures/model.ts
|
|
2
|
+
const isStructureDef = (value) => Boolean(value && typeof value === "object" && value._tag === "Structure");
|
|
3
|
+
const isStructureArrayDef = (value) => Boolean(value && typeof value === "object" && value._tag === "StructureArray");
|
|
4
|
+
|
|
5
|
+
//#endregion
|
|
6
|
+
export { isStructureArrayDef, isStructureDef };
|
|
7
|
+
//# sourceMappingURL=model.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.mjs","names":[],"sources":["../../../src/internal/structures/model.ts"],"sourcesContent":["import { Schema } from \"effect\";\n\nimport type { NodeIdString } from \"../common/node-id.js\";\n\nexport type StructureDef<A> = {\n readonly _tag: \"Structure\";\n readonly name: string;\n readonly dataTypeId: NodeIdString;\n readonly schema: Schema.Codec<unknown, A, never, never>;\n};\n\nexport type StructureArrayDef<A> = {\n readonly _tag: \"StructureArray\";\n readonly item: StructureDef<A>;\n};\n\nexport type AnyStructureDef =\n | StructureDef<unknown>\n | StructureArrayDef<unknown>;\n\nexport const isStructureDef = (\n value: unknown,\n): value is StructureDef<unknown> =>\n Boolean(\n value &&\n typeof value === \"object\" &&\n (value as { readonly _tag?: string })._tag === \"Structure\",\n );\n\nexport const isStructureArrayDef = (\n value: unknown,\n): value is StructureArrayDef<unknown> =>\n Boolean(\n value &&\n typeof value === \"object\" &&\n (value as { readonly _tag?: string })._tag === \"StructureArray\",\n );\n"],"mappings":";AAoBA,MAAa,kBACX,UAEA,QACE,SACA,OAAO,UAAU,YAChB,MAAqC,SAAS,YAChD;AAEH,MAAa,uBACX,UAEA,QACE,SACA,OAAO,UAAU,YAChB,MAAqC,SAAS,iBAChD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { NodeIdString } from "../../OpcuaVariable.mjs";
|
|
2
|
+
import "../common/node-id.mjs";
|
|
3
|
+
import { AnyStructureDef, StructureArrayDef, StructureDef } from "./model.mjs";
|
|
4
|
+
import { OpcuaConfigurationError, OpcuaEncodeError, OpcuaServiceError } from "../../OpcuaError.mjs";
|
|
5
|
+
import { ClientSession, DataType, ExtensionObject, NodeId, Variant } from "node-opcua";
|
|
6
|
+
import { Effect } from "effect";
|
|
7
|
+
|
|
8
|
+
//#region src/internal/structures/runtime.d.ts
|
|
9
|
+
type OpcuaStructureRuntime = {
|
|
10
|
+
readonly ensureInitialized: () => Effect.Effect<void, OpcuaServiceError>;
|
|
11
|
+
readonly invalidate: Effect.Effect<void>;
|
|
12
|
+
readonly encodeStructure: <A>(nodeId: NodeIdString, codec: StructureDef<A>, value: A) => Effect.Effect<ExtensionObject, OpcuaEncodeError | OpcuaServiceError>;
|
|
13
|
+
readonly encodeStructureArray: <A>(nodeId: NodeIdString, codec: StructureArrayDef<A>, values: ReadonlyArray<A>) => Effect.Effect<ReadonlyArray<ExtensionObject>, OpcuaEncodeError | OpcuaServiceError>;
|
|
14
|
+
readonly decodeStructure: <A>(codec: StructureDef<A>, rawValue: unknown) => A;
|
|
15
|
+
readonly decodeStructureArray: <A>(codec: StructureArrayDef<A>, rawValues: unknown) => ReadonlyArray<A>;
|
|
16
|
+
readonly variantFromStructure: <A>(nodeId: NodeIdString, codec: AnyStructureDef, value: A) => Effect.Effect<Variant, OpcuaEncodeError | OpcuaServiceError>;
|
|
17
|
+
};
|
|
18
|
+
declare const makeStructureRuntime: (session: ClientSession) => OpcuaStructureRuntime;
|
|
19
|
+
declare const validateStructureMetadata: (operation: string, nodeId: NodeIdString, metadata: {
|
|
20
|
+
readonly valueRank: number;
|
|
21
|
+
readonly raw: {
|
|
22
|
+
readonly declaredDataType: NodeId;
|
|
23
|
+
readonly builtInDataType: DataType;
|
|
24
|
+
};
|
|
25
|
+
}, structure: AnyStructureDef) => OpcuaConfigurationError | undefined;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { OpcuaStructureRuntime, makeStructureRuntime, validateStructureMetadata };
|
|
28
|
+
//# sourceMappingURL=runtime.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.mts","names":[],"sources":["../../../src/internal/structures/runtime.ts"],"sourcesContent":[],"mappings":";;;;;;;;KAgCY,qBAAA;oCACwB,MAAA,CAAO,aAAa;uBACjC,MAAA,CAAO;EAFlB,SAAA,eAAqB,EAAA,CAAA,CAAA,CAAA,CAAA,MAAA,EAIrB,YAJqB,EAAA,KAAA,EAKtB,YALsB,CAKT,CALS,CAAA,EAAA,KAAA,EAMtB,CANsB,EAAA,GAO1B,MAAA,CAAO,MAPmB,CAOZ,eAPY,EAOK,gBAPL,GAOwB,iBAPxB,CAAA;EACuB,SAAA,oBAAA,EAAA,CAAA,CAAA,CAAA,CAAA,MAAA,EAQ5C,YAR4C,EAAA,KAAA,EAS7C,iBAT6C,CAS3B,CAT2B,CAAA,EAAA,MAAA,EAU5C,aAV4C,CAU9B,CAV8B,CAAA,EAAA,GAWjD,MAAA,CAAO,MAX0C,CAYpD,aAZoD,CAYtC,eAZsC,CAAA,EAapD,gBAboD,GAajC,iBAbiC,CAAA;EAApB,SAAO,eAAA,EAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAeJ,YAfI,CAeS,CAfT,CAAA,EAAA,QAAA,EAAA,OAAA,EAAA,GAemC,CAfnC;EACpB,SAAO,oBAAA,EAAA,CAAA,CAAA,CAAA,CAAA,KAAA,EAgBnB,iBAhBmB,CAgBD,CAhBC,CAAA,EAAA,SAAA,EAAA,OAAA,EAAA,GAkBvB,aAlBuB,CAkBT,CAlBS,CAAA;EAElB,SAAA,oBAAA,EAAA,CAAA,CAAA,CAAA,CAAA,MAAA,EAkBA,YAlBA,EAAA,KAAA,EAmBD,eAnBC,EAAA,KAAA,EAoBD,CApBC,EAAA,GAqBL,MAAA,CAAO,MArBF,CAqBS,OArBT,EAqBkB,gBArBlB,GAqBqC,iBArBrC,CAAA;CACY;AAAb,cAuBE,oBAvBF,EAAA,CAAA,OAAA,EAwBA,aAxBA,EAAA,GAyBR,qBAzBQ;AACA,cA8JE,yBA9JF,EAAA,CAAA,SAAA,EAAA,MAAA,EAAA,MAAA,EAgKD,YAhKC,EAAA,QAAA,EAAA;EACU,SAAA,SAAA,EAAA,MAAA;EAAiB,SAAA,GAAA,EAAA;IAAmB,SAAA,gBAAA,EAmKxB,MAnKwB;IAA3C,SAAA,eAAA,EAoKkB,QApKlB;EAEF,CAAA;CACiB,EAAA,SAAA,EAoKhB,eApKgB,EAAA,GAoKD,uBAAA,GApKC,SAAA"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { isPlainRecord } from "../common/predicates.mjs";
|
|
2
|
+
import { structureBodyFromExtensionObject } from "./adapter.mjs";
|
|
3
|
+
import { configurationError, encodeError, serviceError } from "../../OpcuaError.mjs";
|
|
4
|
+
import { isStructureArrayDef } from "./model.mjs";
|
|
5
|
+
import { decodeWithSchema, encodeWithSchema } from "../values/codec.mjs";
|
|
6
|
+
import { DataType, DataTypeExtractStrategy, Variant, VariantArrayType, coerceNodeId, getExtraDataTypeManager, sameNodeId } from "node-opcua";
|
|
7
|
+
import { Effect } from "effect";
|
|
8
|
+
|
|
9
|
+
//#region src/internal/structures/runtime.ts
|
|
10
|
+
const makeStructureRuntime = (session) => {
|
|
11
|
+
let initializeOnce = makeInitializeOnce(session);
|
|
12
|
+
const ensureInitialized = () => initializeOnce;
|
|
13
|
+
const invalidate = Effect.sync(() => {
|
|
14
|
+
initializeOnce = makeInitializeOnce(session);
|
|
15
|
+
});
|
|
16
|
+
const encodeStructure = (nodeId, codec, value) => Effect.gen(function* () {
|
|
17
|
+
yield* ensureInitialized();
|
|
18
|
+
const pojo = yield* Effect.try({
|
|
19
|
+
try: () => encodeWithSchema(codec.schema, value),
|
|
20
|
+
catch: (error) => encodeError({
|
|
21
|
+
nodeId,
|
|
22
|
+
value,
|
|
23
|
+
error
|
|
24
|
+
})
|
|
25
|
+
});
|
|
26
|
+
return yield* Effect.tryPromise({
|
|
27
|
+
try: () => session.constructExtensionObject(coerceNodeId(codec.dataTypeId), pojoRecord(pojo)),
|
|
28
|
+
catch: (cause) => encodeError({
|
|
29
|
+
nodeId,
|
|
30
|
+
value,
|
|
31
|
+
error: cause,
|
|
32
|
+
cause
|
|
33
|
+
})
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
const encodeStructureArray = (nodeId, codec, values) => Effect.forEach(values, (value) => encodeStructure(nodeId, codec.item, value));
|
|
37
|
+
const decodeStructure = (codec, rawValue) => decodeWithSchema(codec.schema, structureBodyFromExtensionObject(rawValue));
|
|
38
|
+
const decodeStructureArray = (codec, rawValues) => {
|
|
39
|
+
if (!Array.isArray(rawValues)) throw new TypeError(`Expected structure array for ${codec.item.name}`);
|
|
40
|
+
return rawValues.map((value) => decodeStructure(codec.item, value));
|
|
41
|
+
};
|
|
42
|
+
const variantFromStructure = (nodeId, codec, value) => Effect.gen(function* () {
|
|
43
|
+
if (isStructureArrayDef(codec)) {
|
|
44
|
+
const extensionObjects = yield* encodeStructureArray(nodeId, codec, yield* arrayValue(nodeId, value));
|
|
45
|
+
return new Variant({
|
|
46
|
+
dataType: DataType.ExtensionObject,
|
|
47
|
+
arrayType: VariantArrayType.Array,
|
|
48
|
+
value: [...extensionObjects]
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
const extensionObject = yield* encodeStructure(nodeId, codec, value);
|
|
52
|
+
return new Variant({
|
|
53
|
+
dataType: DataType.ExtensionObject,
|
|
54
|
+
arrayType: VariantArrayType.Scalar,
|
|
55
|
+
value: extensionObject
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
ensureInitialized,
|
|
60
|
+
invalidate,
|
|
61
|
+
encodeStructure,
|
|
62
|
+
encodeStructureArray,
|
|
63
|
+
decodeStructure,
|
|
64
|
+
decodeStructureArray,
|
|
65
|
+
variantFromStructure
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
const makeInitializeOnce = (session) => Effect.runSync(Effect.cached(Effect.tryPromise({
|
|
69
|
+
try: () => getExtraDataTypeManager(session, DataTypeExtractStrategy.Both),
|
|
70
|
+
catch: (cause) => serviceError({
|
|
71
|
+
operation: "structure.extractNamespaceDataType",
|
|
72
|
+
cause
|
|
73
|
+
})
|
|
74
|
+
})));
|
|
75
|
+
const pojoRecord = (value) => {
|
|
76
|
+
if (isPlainRecord(value)) return value;
|
|
77
|
+
throw new TypeError("Structure schema must encode to a plain object");
|
|
78
|
+
};
|
|
79
|
+
const arrayValue = (nodeId, value) => Array.isArray(value) ? Effect.succeed(value) : Effect.fail(encodeError({
|
|
80
|
+
nodeId,
|
|
81
|
+
value,
|
|
82
|
+
error: "Structure array value must be an array"
|
|
83
|
+
}));
|
|
84
|
+
const validateStructureMetadata = (operation, nodeId, metadata, structure) => {
|
|
85
|
+
const codec = isStructureArrayDef(structure) ? structure.item : structure;
|
|
86
|
+
if (metadata.raw.builtInDataType !== DataType.ExtensionObject) return configurationError({
|
|
87
|
+
operation,
|
|
88
|
+
nodeId,
|
|
89
|
+
cause: `Expected built-in DataType.ExtensionObject for ${codec.name}`
|
|
90
|
+
});
|
|
91
|
+
const expectedDataType = coerceNodeId(codec.dataTypeId);
|
|
92
|
+
if (!sameNodeId(metadata.raw.declaredDataType, expectedDataType)) return configurationError({
|
|
93
|
+
operation,
|
|
94
|
+
nodeId,
|
|
95
|
+
cause: `Expected exact declared DataType ${expectedDataType.toString()} for ${codec.name}, got ${metadata.raw.declaredDataType.toString()}`
|
|
96
|
+
});
|
|
97
|
+
if (metadata.valueRank > 1) return configurationError({
|
|
98
|
+
operation,
|
|
99
|
+
nodeId,
|
|
100
|
+
cause: "Structure matrices are not supported"
|
|
101
|
+
});
|
|
102
|
+
if (isStructureArrayDef(structure)) {
|
|
103
|
+
if (!isOneDimArrayCompatibleRank(metadata.valueRank)) return configurationError({
|
|
104
|
+
operation,
|
|
105
|
+
nodeId,
|
|
106
|
+
cause: "Expected one-dimensional structure array metadata"
|
|
107
|
+
});
|
|
108
|
+
} else if (!isScalarCompatibleRank(metadata.valueRank)) return configurationError({
|
|
109
|
+
operation,
|
|
110
|
+
nodeId,
|
|
111
|
+
cause: "Expected scalar structure metadata"
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
const isScalarCompatibleRank = (rank) => rank === -1 || rank === -2 || rank === -3;
|
|
115
|
+
const isOneDimArrayCompatibleRank = (rank) => rank === 1 || rank === 0 || rank === -2 || rank === -3;
|
|
116
|
+
|
|
117
|
+
//#endregion
|
|
118
|
+
export { makeStructureRuntime, validateStructureMetadata };
|
|
119
|
+
//# sourceMappingURL=runtime.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.mjs","names":[],"sources":["../../../src/internal/structures/runtime.ts"],"sourcesContent":["import {\n DataType,\n DataTypeExtractStrategy,\n Variant,\n VariantArrayType,\n coerceNodeId,\n getExtraDataTypeManager,\n sameNodeId,\n type ClientSession,\n type ExtensionObject,\n type NodeId,\n} from \"node-opcua\";\nimport { Effect } from \"effect\";\n\nimport type { NodeIdString } from \"../common/node-id.js\";\nimport { encodeWithSchema, decodeWithSchema } from \"../values/codec.js\";\nimport {\n configurationError,\n encodeError,\n serviceError,\n type OpcuaEncodeError,\n type OpcuaServiceError,\n} from \"../../OpcuaError.js\";\nimport {\n isStructureArrayDef,\n type AnyStructureDef,\n type StructureArrayDef,\n type StructureDef,\n} from \"./model.js\";\nimport { isPlainRecord } from \"../common/predicates.js\";\nimport { structureBodyFromExtensionObject } from \"./adapter.js\";\n\nexport type OpcuaStructureRuntime = {\n readonly ensureInitialized: () => Effect.Effect<void, OpcuaServiceError>;\n readonly invalidate: Effect.Effect<void>;\n readonly encodeStructure: <A>(\n nodeId: NodeIdString,\n codec: StructureDef<A>,\n value: A,\n ) => Effect.Effect<ExtensionObject, OpcuaEncodeError | OpcuaServiceError>;\n readonly encodeStructureArray: <A>(\n nodeId: NodeIdString,\n codec: StructureArrayDef<A>,\n values: ReadonlyArray<A>,\n ) => Effect.Effect<\n ReadonlyArray<ExtensionObject>,\n OpcuaEncodeError | OpcuaServiceError\n >;\n readonly decodeStructure: <A>(codec: StructureDef<A>, rawValue: unknown) => A;\n readonly decodeStructureArray: <A>(\n codec: StructureArrayDef<A>,\n rawValues: unknown,\n ) => ReadonlyArray<A>;\n readonly variantFromStructure: <A>(\n nodeId: NodeIdString,\n codec: AnyStructureDef,\n value: A,\n ) => Effect.Effect<Variant, OpcuaEncodeError | OpcuaServiceError>;\n};\n\nexport const makeStructureRuntime = (\n session: ClientSession,\n): OpcuaStructureRuntime => {\n let initializeOnce = makeInitializeOnce(session);\n\n const ensureInitialized = () => initializeOnce;\n const invalidate = Effect.sync(() => {\n initializeOnce = makeInitializeOnce(session);\n });\n\n const encodeStructure = <A>(\n nodeId: NodeIdString,\n codec: StructureDef<A>,\n value: A,\n ) =>\n Effect.gen(function* () {\n yield* ensureInitialized();\n const pojo = yield* Effect.try({\n try: () => encodeWithSchema(codec.schema, value),\n catch: (error) => encodeError({ nodeId, value, error }),\n });\n return yield* Effect.tryPromise({\n try: () =>\n session.constructExtensionObject(\n coerceNodeId(codec.dataTypeId),\n pojoRecord(pojo),\n ),\n catch: (cause) =>\n encodeError({\n nodeId,\n value,\n error: cause,\n cause,\n }),\n });\n });\n\n const encodeStructureArray = <A>(\n nodeId: NodeIdString,\n codec: StructureArrayDef<A>,\n values: ReadonlyArray<A>,\n ) =>\n Effect.forEach(values, (value) =>\n encodeStructure(nodeId, codec.item, value),\n );\n\n const decodeStructure = <A>(codec: StructureDef<A>, rawValue: unknown): A =>\n decodeWithSchema(\n codec.schema,\n structureBodyFromExtensionObject(rawValue),\n ) as A;\n\n const decodeStructureArray = <A>(\n codec: StructureArrayDef<A>,\n rawValues: unknown,\n ): ReadonlyArray<A> => {\n if (!Array.isArray(rawValues)) {\n throw new TypeError(`Expected structure array for ${codec.item.name}`);\n }\n return rawValues.map((value) => decodeStructure(codec.item, value));\n };\n\n const variantFromStructure = <A>(\n nodeId: NodeIdString,\n codec: AnyStructureDef,\n value: A,\n ) =>\n Effect.gen(function* () {\n if (isStructureArrayDef(codec)) {\n const values = yield* arrayValue(nodeId, value);\n const extensionObjects = yield* encodeStructureArray(\n nodeId,\n codec,\n values,\n );\n return new Variant({\n dataType: DataType.ExtensionObject,\n arrayType: VariantArrayType.Array,\n value: [...extensionObjects],\n });\n }\n const extensionObject = yield* encodeStructure(nodeId, codec, value);\n return new Variant({\n dataType: DataType.ExtensionObject,\n arrayType: VariantArrayType.Scalar,\n value: extensionObject,\n });\n });\n\n return {\n ensureInitialized,\n invalidate,\n encodeStructure,\n encodeStructureArray,\n decodeStructure,\n decodeStructureArray,\n variantFromStructure,\n };\n};\n\nconst makeInitializeOnce = (session: ClientSession) =>\n Effect.runSync(\n Effect.cached(\n Effect.tryPromise({\n try: () =>\n getExtraDataTypeManager(session, DataTypeExtractStrategy.Both),\n catch: (cause) =>\n serviceError({\n operation: \"structure.extractNamespaceDataType\",\n cause,\n }),\n }),\n ),\n );\n\nconst pojoRecord = (value: unknown): Record<string, unknown> => {\n if (isPlainRecord(value)) {\n return value as Record<string, unknown>;\n }\n throw new TypeError(\"Structure schema must encode to a plain object\");\n};\n\nconst arrayValue = <A>(\n nodeId: NodeIdString,\n value: A,\n): Effect.Effect<ReadonlyArray<unknown>, OpcuaEncodeError> =>\n Array.isArray(value)\n ? Effect.succeed(value)\n : Effect.fail(\n encodeError({\n nodeId,\n value,\n error: \"Structure array value must be an array\",\n }),\n );\n\nexport const validateStructureMetadata = (\n operation: string,\n nodeId: NodeIdString,\n metadata: {\n readonly valueRank: number;\n readonly raw: {\n readonly declaredDataType: NodeId;\n readonly builtInDataType: DataType;\n };\n },\n structure: AnyStructureDef,\n) => {\n const codec = isStructureArrayDef(structure) ? structure.item : structure;\n if (metadata.raw.builtInDataType !== DataType.ExtensionObject) {\n return configurationError({\n operation,\n nodeId,\n cause: `Expected built-in DataType.ExtensionObject for ${codec.name}`,\n });\n }\n const expectedDataType = coerceNodeId(codec.dataTypeId);\n if (!sameNodeId(metadata.raw.declaredDataType, expectedDataType)) {\n return configurationError({\n operation,\n nodeId,\n cause: `Expected exact declared DataType ${expectedDataType.toString()} for ${codec.name}, got ${metadata.raw.declaredDataType.toString()}`,\n });\n }\n if (metadata.valueRank > 1) {\n return configurationError({\n operation,\n nodeId,\n cause: \"Structure matrices are not supported\",\n });\n }\n if (isStructureArrayDef(structure)) {\n if (!isOneDimArrayCompatibleRank(metadata.valueRank)) {\n return configurationError({\n operation,\n nodeId,\n cause: \"Expected one-dimensional structure array metadata\",\n });\n }\n } else if (!isScalarCompatibleRank(metadata.valueRank)) {\n return configurationError({\n operation,\n nodeId,\n cause: \"Expected scalar structure metadata\",\n });\n }\n return undefined;\n};\n\nconst isScalarCompatibleRank = (rank: number) =>\n rank === -1 || rank === -2 || rank === -3;\n\nconst isOneDimArrayCompatibleRank = (rank: number) =>\n rank === 1 || rank === 0 || rank === -2 || rank === -3;\n"],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { OpcuaConfigurationError } from "../../OpcuaError.mjs";
|
|
2
|
+
import { SubscriptionOptions } from "../../OpcuaSession.mjs";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/internal/subscription/options.d.ts
|
|
6
|
+
type NormalizedSubscriptionOptions = {
|
|
7
|
+
readonly publishingInterval: number;
|
|
8
|
+
readonly lifetimeCount: number;
|
|
9
|
+
readonly maxKeepAliveCount: number;
|
|
10
|
+
readonly maxNotificationsPerPublish: number;
|
|
11
|
+
readonly publishingEnabled: boolean;
|
|
12
|
+
readonly priority: number;
|
|
13
|
+
};
|
|
14
|
+
declare const validateSubscriptionOptions: (options: SubscriptionOptions) => Effect.Effect<NormalizedSubscriptionOptions, OpcuaConfigurationError>;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { NormalizedSubscriptionOptions, validateSubscriptionOptions };
|
|
17
|
+
//# sourceMappingURL=options.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.d.mts","names":[],"sources":["../../../src/internal/subscription/options.ts"],"sourcesContent":[],"mappings":";;;;;KAsBY,6BAAA;;EAAA,SAAA,aAAA,EAAA,MAAA;EAkBC,SAAA,iBAAA,EAAA,MA2ET;EA1EO,SAAA,0BAAA,EAAA,MAAA;EACM,SAAA,iBAAA,EAAA,OAAA;EAA+B,SAAA,QAAA,EAAA,MAAA;CAA7C;AAAa,cAFH,2BAEG,EAAA,CAAA,OAAA,EADL,mBACK,EAAA,GAAb,MAAA,CAAO,MAAM,CAAC,6BAAD,EAAgC,uBAAhC,CAAA"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { isPlainRecord } from "../common/predicates.mjs";
|
|
2
|
+
import { configurationError } from "../../OpcuaError.mjs";
|
|
3
|
+
import { durationToMillis, nonNegativeIntegerOption, positiveIntegerOption, unknownKeys } from "../common/options.mjs";
|
|
4
|
+
import { DEFAULT_LIFETIME_COUNT, DEFAULT_MAX_KEEP_ALIVE_COUNT, DEFAULT_MAX_NOTIFICATIONS_PER_PUBLISH, DEFAULT_PRIORITY, DEFAULT_PUBLISHING_ENABLED } from "../common/constants.mjs";
|
|
5
|
+
import { Effect } from "effect";
|
|
6
|
+
|
|
7
|
+
//#region src/internal/subscription/options.ts
|
|
8
|
+
const allowedSubscriptionOptionKeys = new Set([
|
|
9
|
+
"publishingInterval",
|
|
10
|
+
"lifetimeCount",
|
|
11
|
+
"maxKeepAliveCount",
|
|
12
|
+
"maxNotificationsPerPublish",
|
|
13
|
+
"publishingEnabled",
|
|
14
|
+
"priority"
|
|
15
|
+
]);
|
|
16
|
+
const validateSubscriptionOptions = (options) => Effect.suspend(() => {
|
|
17
|
+
if (!isPlainRecord(options)) return Effect.fail(subscriptionOptionsError("options must be an object"));
|
|
18
|
+
const unknown = unknownKeys(options, allowedSubscriptionOptionKeys);
|
|
19
|
+
if (unknown.length > 0) return Effect.fail(subscriptionOptionsError(`unsupported option: ${unknown.join(", ")}`));
|
|
20
|
+
const publishingInterval = durationToMillis(options.publishingInterval, {
|
|
21
|
+
notDuration: "publishingInterval must be a Duration",
|
|
22
|
+
invalidDuration: "publishingInterval must be finite and non-negative"
|
|
23
|
+
});
|
|
24
|
+
if (typeof publishingInterval === "string") return Effect.fail(subscriptionOptionsError(publishingInterval));
|
|
25
|
+
const lifetimeCount = options.lifetimeCount ?? DEFAULT_LIFETIME_COUNT;
|
|
26
|
+
if (!positiveIntegerOption(lifetimeCount)) return Effect.fail(subscriptionOptionsError("lifetimeCount must be a positive integer"));
|
|
27
|
+
const maxKeepAliveCount = options.maxKeepAliveCount ?? DEFAULT_MAX_KEEP_ALIVE_COUNT;
|
|
28
|
+
if (!positiveIntegerOption(maxKeepAliveCount)) return Effect.fail(subscriptionOptionsError("maxKeepAliveCount must be a positive integer"));
|
|
29
|
+
const maxNotificationsPerPublish = options.maxNotificationsPerPublish ?? DEFAULT_MAX_NOTIFICATIONS_PER_PUBLISH;
|
|
30
|
+
if (!nonNegativeIntegerOption(maxNotificationsPerPublish)) return Effect.fail(subscriptionOptionsError("maxNotificationsPerPublish must be a non-negative integer"));
|
|
31
|
+
const publishingEnabled = options.publishingEnabled ?? DEFAULT_PUBLISHING_ENABLED;
|
|
32
|
+
if (typeof publishingEnabled !== "boolean") return Effect.fail(subscriptionOptionsError("publishingEnabled must be a boolean"));
|
|
33
|
+
const priority = options.priority ?? DEFAULT_PRIORITY;
|
|
34
|
+
if (!nonNegativeIntegerOption(priority) || priority > 255) return Effect.fail(subscriptionOptionsError("priority must be an integer between 0 and 255"));
|
|
35
|
+
return Effect.succeed({
|
|
36
|
+
publishingInterval,
|
|
37
|
+
lifetimeCount,
|
|
38
|
+
maxKeepAliveCount,
|
|
39
|
+
maxNotificationsPerPublish,
|
|
40
|
+
publishingEnabled,
|
|
41
|
+
priority
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
const subscriptionOptionsError = (cause) => configurationError({
|
|
45
|
+
operation: "subscription.options",
|
|
46
|
+
cause
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
export { validateSubscriptionOptions };
|
|
51
|
+
//# sourceMappingURL=options.mjs.map
|