@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.
Files changed (171) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +367 -0
  3. package/dist/Opcua.d.mts +13 -0
  4. package/dist/Opcua.d.mts.map +1 -0
  5. package/dist/Opcua.mjs +23 -0
  6. package/dist/Opcua.mjs.map +1 -0
  7. package/dist/OpcuaClient.d.mts +27 -0
  8. package/dist/OpcuaClient.d.mts.map +1 -0
  9. package/dist/OpcuaClient.mjs +20 -0
  10. package/dist/OpcuaClient.mjs.map +1 -0
  11. package/dist/OpcuaError.d.mts +249 -0
  12. package/dist/OpcuaError.d.mts.map +1 -0
  13. package/dist/OpcuaError.mjs +97 -0
  14. package/dist/OpcuaError.mjs.map +1 -0
  15. package/dist/OpcuaMethod.d.mts +158 -0
  16. package/dist/OpcuaMethod.d.mts.map +1 -0
  17. package/dist/OpcuaMethod.mjs +31 -0
  18. package/dist/OpcuaMethod.mjs.map +1 -0
  19. package/dist/OpcuaSession.d.mts +247 -0
  20. package/dist/OpcuaSession.d.mts.map +1 -0
  21. package/dist/OpcuaSession.mjs +50 -0
  22. package/dist/OpcuaSession.mjs.map +1 -0
  23. package/dist/OpcuaSubscription.d.mts +148 -0
  24. package/dist/OpcuaSubscription.d.mts.map +1 -0
  25. package/dist/OpcuaSubscription.mjs +45 -0
  26. package/dist/OpcuaSubscription.mjs.map +1 -0
  27. package/dist/OpcuaVariable.d.mts +179 -0
  28. package/dist/OpcuaVariable.d.mts.map +1 -0
  29. package/dist/OpcuaVariable.mjs +15 -0
  30. package/dist/OpcuaVariable.mjs.map +1 -0
  31. package/dist/_virtual/rolldown_runtime.mjs +18 -0
  32. package/dist/index.d.mts +8 -0
  33. package/dist/index.mjs +7 -0
  34. package/dist/internal/batch/chunk.d.mts +11 -0
  35. package/dist/internal/batch/chunk.d.mts.map +1 -0
  36. package/dist/internal/batch/chunk.mjs +23 -0
  37. package/dist/internal/batch/chunk.mjs.map +1 -0
  38. package/dist/internal/batch/keyed.d.mts +50 -0
  39. package/dist/internal/batch/keyed.d.mts.map +1 -0
  40. package/dist/internal/batch/keyed.mjs +112 -0
  41. package/dist/internal/batch/keyed.mjs.map +1 -0
  42. package/dist/internal/batch/operations.d.mts +25 -0
  43. package/dist/internal/batch/operations.d.mts.map +1 -0
  44. package/dist/internal/batch/operations.mjs +213 -0
  45. package/dist/internal/batch/operations.mjs.map +1 -0
  46. package/dist/internal/browse/operations.d.mts +15 -0
  47. package/dist/internal/browse/operations.d.mts.map +1 -0
  48. package/dist/internal/browse/operations.mjs +72 -0
  49. package/dist/internal/browse/operations.mjs.map +1 -0
  50. package/dist/internal/client/make.d.mts +16 -0
  51. package/dist/internal/client/make.d.mts.map +1 -0
  52. package/dist/internal/client/make.mjs +76 -0
  53. package/dist/internal/client/make.mjs.map +1 -0
  54. package/dist/internal/common/collections.d.mts +5 -0
  55. package/dist/internal/common/collections.d.mts.map +1 -0
  56. package/dist/internal/common/collections.mjs +10 -0
  57. package/dist/internal/common/collections.mjs.map +1 -0
  58. package/dist/internal/common/constants.d.mts +18 -0
  59. package/dist/internal/common/constants.d.mts.map +1 -0
  60. package/dist/internal/common/constants.mjs +19 -0
  61. package/dist/internal/common/constants.mjs.map +1 -0
  62. package/dist/internal/common/node-id.d.mts +2 -0
  63. package/dist/internal/common/node-id.mjs +1 -0
  64. package/dist/internal/common/options.d.mts +15 -0
  65. package/dist/internal/common/options.d.mts.map +1 -0
  66. package/dist/internal/common/options.mjs +22 -0
  67. package/dist/internal/common/options.mjs.map +1 -0
  68. package/dist/internal/common/predicates.d.mts +8 -0
  69. package/dist/internal/common/predicates.d.mts.map +1 -0
  70. package/dist/internal/common/predicates.mjs +13 -0
  71. package/dist/internal/common/predicates.mjs.map +1 -0
  72. package/dist/internal/data-types/enum.d.mts +2 -0
  73. package/dist/internal/data-types/enum.mjs +3 -0
  74. package/dist/internal/data-types/manager.d.mts +2 -0
  75. package/dist/internal/data-types/manager.mjs +3 -0
  76. package/dist/internal/data-types/model.d.mts +2 -0
  77. package/dist/internal/data-types/model.mjs +1 -0
  78. package/dist/internal/data-types/read.d.mts +14 -0
  79. package/dist/internal/data-types/read.d.mts.map +1 -0
  80. package/dist/internal/data-types/read.mjs +291 -0
  81. package/dist/internal/data-types/read.mjs.map +1 -0
  82. package/dist/internal/data-types/structure.d.mts +2 -0
  83. package/dist/internal/data-types/structure.mjs +3 -0
  84. package/dist/internal/events/model.d.mts +72 -0
  85. package/dist/internal/events/model.d.mts.map +1 -0
  86. package/dist/internal/events/model.mjs +1 -0
  87. package/dist/internal/events/wire.d.mts +37 -0
  88. package/dist/internal/events/wire.d.mts.map +1 -0
  89. package/dist/internal/events/wire.mjs +127 -0
  90. package/dist/internal/events/wire.mjs.map +1 -0
  91. package/dist/internal/metadata/arguments.d.mts +2 -0
  92. package/dist/internal/metadata/arguments.mjs +3 -0
  93. package/dist/internal/metadata/methods.d.mts +2 -0
  94. package/dist/internal/metadata/methods.mjs +3 -0
  95. package/dist/internal/metadata/service.d.mts +23 -0
  96. package/dist/internal/metadata/service.d.mts.map +1 -0
  97. package/dist/internal/metadata/service.mjs +416 -0
  98. package/dist/internal/metadata/service.mjs.map +1 -0
  99. package/dist/internal/metadata/variables.d.mts +3 -0
  100. package/dist/internal/metadata/variables.mjs +3 -0
  101. package/dist/internal/method/arguments.d.mts +48 -0
  102. package/dist/internal/method/arguments.d.mts.map +1 -0
  103. package/dist/internal/method/arguments.mjs +216 -0
  104. package/dist/internal/method/arguments.mjs.map +1 -0
  105. package/dist/internal/method/operations.d.mts +19 -0
  106. package/dist/internal/method/operations.d.mts.map +1 -0
  107. package/dist/internal/method/operations.mjs +111 -0
  108. package/dist/internal/method/operations.mjs.map +1 -0
  109. package/dist/internal/monitoring/options.d.mts +30 -0
  110. package/dist/internal/monitoring/options.d.mts.map +1 -0
  111. package/dist/internal/monitoring/options.mjs +260 -0
  112. package/dist/internal/monitoring/options.mjs.map +1 -0
  113. package/dist/internal/monitoring/requests.d.mts +16 -0
  114. package/dist/internal/monitoring/requests.d.mts.map +1 -0
  115. package/dist/internal/monitoring/requests.mjs +53 -0
  116. package/dist/internal/monitoring/requests.mjs.map +1 -0
  117. package/dist/internal/monitoring/runtime.d.mts +14 -0
  118. package/dist/internal/monitoring/runtime.d.mts.map +1 -0
  119. package/dist/internal/monitoring/runtime.mjs +321 -0
  120. package/dist/internal/monitoring/runtime.mjs.map +1 -0
  121. package/dist/internal/monitoring/samples.d.mts +23 -0
  122. package/dist/internal/monitoring/samples.d.mts.map +1 -0
  123. package/dist/internal/monitoring/samples.mjs +45 -0
  124. package/dist/internal/monitoring/samples.mjs.map +1 -0
  125. package/dist/internal/session/make.d.mts +11 -0
  126. package/dist/internal/session/make.d.mts.map +1 -0
  127. package/dist/internal/session/make.mjs +36 -0
  128. package/dist/internal/session/make.mjs.map +1 -0
  129. package/dist/internal/session/service.d.mts +10 -0
  130. package/dist/internal/session/service.d.mts.map +1 -0
  131. package/dist/internal/session/service.mjs +232 -0
  132. package/dist/internal/session/service.mjs.map +1 -0
  133. package/dist/internal/structures/adapter.d.mts +11 -0
  134. package/dist/internal/structures/adapter.d.mts.map +1 -0
  135. package/dist/internal/structures/adapter.mjs +37 -0
  136. package/dist/internal/structures/adapter.mjs.map +1 -0
  137. package/dist/internal/structures/model.d.mts +21 -0
  138. package/dist/internal/structures/model.d.mts.map +1 -0
  139. package/dist/internal/structures/model.mjs +7 -0
  140. package/dist/internal/structures/model.mjs.map +1 -0
  141. package/dist/internal/structures/runtime.d.mts +28 -0
  142. package/dist/internal/structures/runtime.d.mts.map +1 -0
  143. package/dist/internal/structures/runtime.mjs +119 -0
  144. package/dist/internal/structures/runtime.mjs.map +1 -0
  145. package/dist/internal/subscription/options.d.mts +17 -0
  146. package/dist/internal/subscription/options.d.mts.map +1 -0
  147. package/dist/internal/subscription/options.mjs +51 -0
  148. package/dist/internal/subscription/options.mjs.map +1 -0
  149. package/dist/internal/subscription/runtime.d.mts +15 -0
  150. package/dist/internal/subscription/runtime.d.mts.map +1 -0
  151. package/dist/internal/subscription/runtime.mjs +43 -0
  152. package/dist/internal/subscription/runtime.mjs.map +1 -0
  153. package/dist/internal/values/codec.d.mts +53 -0
  154. package/dist/internal/values/codec.d.mts.map +1 -0
  155. package/dist/internal/values/codec.mjs +117 -0
  156. package/dist/internal/values/codec.mjs.map +1 -0
  157. package/dist/internal/values/normalize.d.mts +33 -0
  158. package/dist/internal/values/normalize.d.mts.map +1 -0
  159. package/dist/internal/values/normalize.mjs +177 -0
  160. package/dist/internal/values/normalize.mjs.map +1 -0
  161. package/dist/internal/values/result.d.mts +16 -0
  162. package/dist/internal/values/result.d.mts.map +1 -0
  163. package/dist/internal/values/result.mjs +15 -0
  164. package/dist/internal/values/result.mjs.map +1 -0
  165. package/dist/internal/variable/operations.d.mts +50 -0
  166. package/dist/internal/variable/operations.d.mts.map +1 -0
  167. package/dist/internal/variable/operations.mjs +192 -0
  168. package/dist/internal/variable/operations.mjs.map +1 -0
  169. package/dist/node-opcua.d.mts +2 -0
  170. package/dist/node-opcua.mjs +3 -0
  171. package/package.json +57 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.mjs","names":[],"sources":["../../../src/internal/subscription/options.ts"],"sourcesContent":["import { Effect } from \"effect\";\n\nimport {\n DEFAULT_LIFETIME_COUNT,\n DEFAULT_MAX_KEEP_ALIVE_COUNT,\n DEFAULT_MAX_NOTIFICATIONS_PER_PUBLISH,\n DEFAULT_PRIORITY,\n DEFAULT_PUBLISHING_ENABLED,\n} from \"../common/constants.js\";\nimport {\n durationToMillis,\n nonNegativeIntegerOption,\n positiveIntegerOption,\n unknownKeys,\n} from \"../common/options.js\";\nimport { isPlainRecord } from \"../common/predicates.js\";\nimport {\n configurationError,\n type OpcuaConfigurationError,\n} from \"../../OpcuaError.js\";\nimport type { SubscriptionOptions } from \"../../OpcuaSession.js\";\n\nexport type NormalizedSubscriptionOptions = {\n readonly publishingInterval: number;\n readonly lifetimeCount: number;\n readonly maxKeepAliveCount: number;\n readonly maxNotificationsPerPublish: number;\n readonly publishingEnabled: boolean;\n readonly priority: number;\n};\n\nconst allowedSubscriptionOptionKeys = new Set([\n \"publishingInterval\",\n \"lifetimeCount\",\n \"maxKeepAliveCount\",\n \"maxNotificationsPerPublish\",\n \"publishingEnabled\",\n \"priority\",\n]);\n\nexport const validateSubscriptionOptions = (\n options: SubscriptionOptions,\n): Effect.Effect<NormalizedSubscriptionOptions, OpcuaConfigurationError> =>\n Effect.suspend(() => {\n if (!isPlainRecord(options)) {\n return Effect.fail(subscriptionOptionsError(\"options must be an object\"));\n }\n const unknown = unknownKeys(options, allowedSubscriptionOptionKeys);\n if (unknown.length > 0) {\n return Effect.fail(\n subscriptionOptionsError(`unsupported option: ${unknown.join(\", \")}`),\n );\n }\n\n const publishingInterval = durationToMillis(options.publishingInterval, {\n notDuration: \"publishingInterval must be a Duration\",\n invalidDuration: \"publishingInterval must be finite and non-negative\",\n });\n if (typeof publishingInterval === \"string\") {\n return Effect.fail(subscriptionOptionsError(publishingInterval));\n }\n\n const lifetimeCount = options.lifetimeCount ?? DEFAULT_LIFETIME_COUNT;\n if (!positiveIntegerOption(lifetimeCount)) {\n return Effect.fail(\n subscriptionOptionsError(\"lifetimeCount must be a positive integer\"),\n );\n }\n\n const maxKeepAliveCount =\n options.maxKeepAliveCount ?? DEFAULT_MAX_KEEP_ALIVE_COUNT;\n if (!positiveIntegerOption(maxKeepAliveCount)) {\n return Effect.fail(\n subscriptionOptionsError(\n \"maxKeepAliveCount must be a positive integer\",\n ),\n );\n }\n\n const maxNotificationsPerPublish =\n options.maxNotificationsPerPublish ??\n DEFAULT_MAX_NOTIFICATIONS_PER_PUBLISH;\n if (!nonNegativeIntegerOption(maxNotificationsPerPublish)) {\n return Effect.fail(\n subscriptionOptionsError(\n \"maxNotificationsPerPublish must be a non-negative integer\",\n ),\n );\n }\n\n const publishingEnabled =\n options.publishingEnabled ?? DEFAULT_PUBLISHING_ENABLED;\n if (typeof publishingEnabled !== \"boolean\") {\n return Effect.fail(\n subscriptionOptionsError(\"publishingEnabled must be a boolean\"),\n );\n }\n\n const priority = options.priority ?? DEFAULT_PRIORITY;\n if (!nonNegativeIntegerOption(priority) || priority > 255) {\n return Effect.fail(\n subscriptionOptionsError(\n \"priority must be an integer between 0 and 255\",\n ),\n );\n }\n\n return Effect.succeed({\n publishingInterval,\n lifetimeCount,\n maxKeepAliveCount,\n maxNotificationsPerPublish,\n publishingEnabled,\n priority,\n });\n });\n\nconst subscriptionOptionsError = (cause: unknown) =>\n configurationError({\n operation: \"subscription.options\",\n cause,\n });\n"],"mappings":";;;;;;;AA+BA,MAAM,gCAAgC,IAAI,IAAI;CAC5C;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,MAAa,+BACX,YAEA,OAAO,cAAc;AACnB,KAAI,CAAC,cAAc,QAAQ,CACzB,QAAO,OAAO,KAAK,yBAAyB,4BAA4B,CAAC;CAE3E,MAAM,UAAU,YAAY,SAAS,8BAA8B;AACnE,KAAI,QAAQ,SAAS,EACnB,QAAO,OAAO,KACZ,yBAAyB,uBAAuB,QAAQ,KAAK,KAAK,GAAG,CACtE;CAGH,MAAM,qBAAqB,iBAAiB,QAAQ,oBAAoB;EACtE,aAAa;EACb,iBAAiB;EAClB,CAAC;AACF,KAAI,OAAO,uBAAuB,SAChC,QAAO,OAAO,KAAK,yBAAyB,mBAAmB,CAAC;CAGlE,MAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,KAAI,CAAC,sBAAsB,cAAc,CACvC,QAAO,OAAO,KACZ,yBAAyB,2CAA2C,CACrE;CAGH,MAAM,oBACJ,QAAQ,qBAAqB;AAC/B,KAAI,CAAC,sBAAsB,kBAAkB,CAC3C,QAAO,OAAO,KACZ,yBACE,+CACD,CACF;CAGH,MAAM,6BACJ,QAAQ,8BACR;AACF,KAAI,CAAC,yBAAyB,2BAA2B,CACvD,QAAO,OAAO,KACZ,yBACE,4DACD,CACF;CAGH,MAAM,oBACJ,QAAQ,qBAAqB;AAC/B,KAAI,OAAO,sBAAsB,UAC/B,QAAO,OAAO,KACZ,yBAAyB,sCAAsC,CAChE;CAGH,MAAM,WAAW,QAAQ,YAAY;AACrC,KAAI,CAAC,yBAAyB,SAAS,IAAI,WAAW,IACpD,QAAO,OAAO,KACZ,yBACE,gDACD,CACF;AAGH,QAAO,OAAO,QAAQ;EACpB;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;EACF;AAEJ,MAAM,4BAA4B,UAChC,mBAAmB;CACjB,WAAW;CACX;CACD,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { OpcuaStructureRuntime } from "../structures/runtime.mjs";
2
+ import { ValidateVariable } from "../monitoring/runtime.mjs";
3
+ import { OpcuaSubscription } from "../../OpcuaSubscription.mjs";
4
+ import { OpcuaConfigurationError, OpcuaSubscriptionCreateError } from "../../OpcuaError.mjs";
5
+ import { SubscriptionOptions } from "../../OpcuaSession.mjs";
6
+ import { validateSubscriptionOptions } from "./options.mjs";
7
+ import { ClientSession } from "node-opcua";
8
+ import { Effect } from "effect";
9
+ import * as effect_Scope0 from "effect/Scope";
10
+
11
+ //#region src/internal/subscription/runtime.d.ts
12
+ declare const makeSubscriptionRuntime: (unsafeRawSession: ClientSession, options: SubscriptionOptions, structureRuntime: OpcuaStructureRuntime, validateVariable: ValidateVariable) => Effect.Effect<OpcuaSubscription, OpcuaConfigurationError | OpcuaSubscriptionCreateError, effect_Scope0.Scope>;
13
+ //#endregion
14
+ export { makeSubscriptionRuntime, validateSubscriptionOptions };
15
+ //# sourceMappingURL=runtime.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.mts","names":[],"sources":["../../../src/internal/subscription/runtime.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;cAea,4CAAuB,wBAAA,uCAAA,yCAAA,qBAAA,MAAA,CAAA,OAAA,iBAAA,EAAA,0BAAA,8BAAA,aAAA,CAAA,KAAA"}
@@ -0,0 +1,43 @@
1
+ import { subscriptionCreateError } from "../../OpcuaError.mjs";
2
+ import { wireSubscriptionEvents } from "../events/wire.mjs";
3
+ import { makeSubscriptionService } from "../monitoring/runtime.mjs";
4
+ import { EVENT_BUFFER_SIZE } from "../common/constants.mjs";
5
+ import { validateSubscriptionOptions } from "./options.mjs";
6
+ import { ClientSubscription } from "node-opcua";
7
+ import { Effect, PubSub } from "effect";
8
+
9
+ //#region src/internal/subscription/runtime.ts
10
+ const makeSubscriptionRuntime = Effect.fnUntraced(function* (unsafeRawSession, options, structureRuntime, validateVariable) {
11
+ const normalized = yield* validateSubscriptionOptions(options);
12
+ const events = yield* PubSub.sliding({
13
+ capacity: EVENT_BUFFER_SIZE,
14
+ replay: 1
15
+ });
16
+ yield* Effect.addFinalizer(() => PubSub.shutdown(events));
17
+ const unsafeRaw = yield* Effect.acquireRelease(Effect.tryPromise({
18
+ try: async () => ClientSubscription.create(unsafeRawSession, {
19
+ requestedPublishingInterval: normalized.publishingInterval,
20
+ requestedLifetimeCount: normalized.lifetimeCount,
21
+ requestedMaxKeepAliveCount: normalized.maxKeepAliveCount,
22
+ maxNotificationsPerPublish: normalized.maxNotificationsPerPublish,
23
+ publishingEnabled: normalized.publishingEnabled,
24
+ priority: normalized.priority
25
+ }),
26
+ catch: (cause) => subscriptionCreateError({ cause })
27
+ }).pipe(Effect.withSpan("opcua.subscription.create", {
28
+ attributes: { "opcua.publishing_interval_ms": normalized.publishingInterval },
29
+ kind: "client"
30
+ })), (subscription) => Effect.tryPromise({
31
+ try: () => subscription.terminate(),
32
+ catch: (cause) => subscriptionCreateError({ cause })
33
+ }).pipe(Effect.withSpan("opcua.subscription.terminate", {
34
+ attributes: { "opcua.subscription_id": subscription.subscriptionId },
35
+ kind: "client"
36
+ }), Effect.ignore));
37
+ yield* wireSubscriptionEvents(unsafeRaw, events);
38
+ return makeSubscriptionService(unsafeRaw, events, structureRuntime, validateVariable);
39
+ });
40
+
41
+ //#endregion
42
+ export { makeSubscriptionRuntime, validateSubscriptionOptions };
43
+ //# sourceMappingURL=runtime.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.mjs","names":["OpcuaError.subscriptionCreateError"],"sources":["../../../src/internal/subscription/runtime.ts"],"sourcesContent":["import { ClientSubscription, type ClientSession } from \"node-opcua\";\nimport { Effect, PubSub } from \"effect\";\n\nimport * as OpcuaError from \"../../OpcuaError.js\";\nimport type * as OpcuaSession from \"../../OpcuaSession.js\";\nimport { EVENT_BUFFER_SIZE } from \"../common/constants.js\";\nimport type { OpcuaSubscriptionEvent } from \"../events/model.js\";\nimport { wireSubscriptionEvents } from \"../events/wire.js\";\nimport {\n makeSubscriptionService,\n type ValidateVariable,\n} from \"../monitoring/runtime.js\";\nimport type { OpcuaStructureRuntime } from \"../structures/runtime.js\";\nimport { validateSubscriptionOptions } from \"./options.js\";\n\nexport const makeSubscriptionRuntime = Effect.fnUntraced(function* (\n unsafeRawSession: ClientSession,\n options: OpcuaSession.SubscriptionOptions,\n structureRuntime: OpcuaStructureRuntime,\n validateVariable: ValidateVariable,\n) {\n const normalized = yield* validateSubscriptionOptions(options);\n const events = yield* PubSub.sliding<OpcuaSubscriptionEvent>({\n capacity: EVENT_BUFFER_SIZE,\n replay: 1,\n });\n yield* Effect.addFinalizer(() => PubSub.shutdown(events));\n\n const unsafeRaw = yield* Effect.acquireRelease(\n Effect.tryPromise({\n try: async () =>\n ClientSubscription.create(unsafeRawSession, {\n requestedPublishingInterval: normalized.publishingInterval,\n requestedLifetimeCount: normalized.lifetimeCount,\n requestedMaxKeepAliveCount: normalized.maxKeepAliveCount,\n maxNotificationsPerPublish: normalized.maxNotificationsPerPublish,\n publishingEnabled: normalized.publishingEnabled,\n priority: normalized.priority,\n }),\n catch: (cause) => OpcuaError.subscriptionCreateError({ cause }),\n }).pipe(\n Effect.withSpan(\"opcua.subscription.create\", {\n attributes: {\n \"opcua.publishing_interval_ms\": normalized.publishingInterval,\n },\n kind: \"client\",\n }),\n ),\n (subscription) =>\n Effect.tryPromise({\n try: () => subscription.terminate(),\n catch: (cause) => OpcuaError.subscriptionCreateError({ cause }),\n }).pipe(\n Effect.withSpan(\"opcua.subscription.terminate\", {\n attributes: {\n \"opcua.subscription_id\": subscription.subscriptionId,\n },\n kind: \"client\",\n }),\n Effect.ignore,\n ),\n );\n yield* wireSubscriptionEvents(unsafeRaw, events);\n return makeSubscriptionService(\n unsafeRaw,\n events,\n structureRuntime,\n validateVariable,\n );\n});\n\nexport { validateSubscriptionOptions };\n"],"mappings":";;;;;;;;;AAeA,MAAa,0BAA0B,OAAO,WAAW,WACvD,kBACA,SACA,kBACA,kBACA;CACA,MAAM,aAAa,OAAO,4BAA4B,QAAQ;CAC9D,MAAM,SAAS,OAAO,OAAO,QAAgC;EAC3D,UAAU;EACV,QAAQ;EACT,CAAC;AACF,QAAO,OAAO,mBAAmB,OAAO,SAAS,OAAO,CAAC;CAEzD,MAAM,YAAY,OAAO,OAAO,eAC9B,OAAO,WAAW;EAChB,KAAK,YACH,mBAAmB,OAAO,kBAAkB;GAC1C,6BAA6B,WAAW;GACxC,wBAAwB,WAAW;GACnC,4BAA4B,WAAW;GACvC,4BAA4B,WAAW;GACvC,mBAAmB,WAAW;GAC9B,UAAU,WAAW;GACtB,CAAC;EACJ,QAAQ,UAAUA,wBAAmC,EAAE,OAAO,CAAC;EAChE,CAAC,CAAC,KACD,OAAO,SAAS,6BAA6B;EAC3C,YAAY,EACV,gCAAgC,WAAW,oBAC5C;EACD,MAAM;EACP,CAAC,CACH,GACA,iBACC,OAAO,WAAW;EAChB,WAAW,aAAa,WAAW;EACnC,QAAQ,UAAUA,wBAAmC,EAAE,OAAO,CAAC;EAChE,CAAC,CAAC,KACD,OAAO,SAAS,gCAAgC;EAC9C,YAAY,EACV,yBAAyB,aAAa,gBACvC;EACD,MAAM;EACP,CAAC,EACF,OAAO,OACR,CACJ;AACD,QAAO,uBAAuB,WAAW,OAAO;AAChD,QAAO,wBACL,WACA,QACA,kBACA,iBACD;EACD"}
@@ -0,0 +1,53 @@
1
+ import { NodeIdString, OpcuaDynamicValue } from "../../OpcuaVariable.mjs";
2
+ import "../common/node-id.mjs";
3
+ import { StructureArrayDef, StructureDef } from "../structures/model.mjs";
4
+ import { OpcuaStructureRuntime } from "../structures/runtime.mjs";
5
+ import { OpcuaConfigurationError, OpcuaEncodeError, OpcuaServiceError } from "../../OpcuaError.mjs";
6
+ import { OpcuaDynamicValueMetadata } from "./normalize.mjs";
7
+ import * as node_opcua0 from "node-opcua";
8
+ import { DataType, DataValue, Variant } from "node-opcua";
9
+ import { Effect, Schema } from "effect";
10
+
11
+ //#region src/internal/values/codec.d.ts
12
+ type AnySchema = Schema.Codec<unknown, unknown, never, never>;
13
+ type SchemaType<S extends AnySchema> = Schema.Schema.Type<S>;
14
+ type OpcuaCodec<A$1> = {
15
+ readonly _tag: "Dynamic";
16
+ readonly _A?: A$1;
17
+ } | {
18
+ readonly _tag: "Schema";
19
+ readonly schema: AnySchema;
20
+ readonly _A?: A$1;
21
+ } | StructureDef<A$1> | (unknown extends A$1 ? StructureArrayDef<unknown> : A$1 extends ReadonlyArray<infer Item> ? StructureArrayDef<Item> : never);
22
+ type CodecType<C> = C extends StructureArrayDef<infer A> ? ReadonlyArray<A> : C extends OpcuaCodec<infer A> ? A : never;
23
+ type CodecMetadata = {
24
+ readonly nodeId: NodeIdString;
25
+ readonly valueRank: number;
26
+ readonly arrayDimensions?: ReadonlyArray<number>;
27
+ readonly raw: {
28
+ readonly declaredDataType: node_opcua0.NodeId;
29
+ readonly builtInDataType: DataType;
30
+ };
31
+ };
32
+ declare const dynamic: <A$1 = OpcuaDynamicValue>() => OpcuaCodec<A$1>;
33
+ declare const schema: <S extends AnySchema>(schema: S) => OpcuaCodec<SchemaType<S>>;
34
+ declare const structure: <S extends AnySchema>(options: {
35
+ readonly name: string;
36
+ readonly dataTypeId: NodeIdString;
37
+ readonly schema: S;
38
+ }) => StructureDef<SchemaType<S>>;
39
+ declare const structureArray: <A$1>(structure: StructureDef<A$1>) => StructureArrayDef<A$1>;
40
+ declare const Codec: {
41
+ encode: <A$1>(codec: OpcuaCodec<A$1>, value: A$1, metadata: CodecMetadata, structureRuntime: OpcuaStructureRuntime) => Effect.Effect<Variant, OpcuaEncodeError | OpcuaServiceError, never>;
42
+ decode: <A$1>(codec: OpcuaCodec<A$1>, variant: Variant | undefined, dataValue: DataValue | undefined, structureRuntime: OpcuaStructureRuntime) => Effect.Effect<A$1, unknown, never>;
43
+ validateMetadata: (codec: OpcuaCodec<unknown>, metadata: CodecMetadata) => Effect.Effect<void, OpcuaConfigurationError, never>;
44
+ requiresStructureRuntime: (codec: OpcuaCodec<unknown>) => codec is StructureDef<unknown> | StructureArrayDef<unknown>;
45
+ };
46
+ declare const encodeWithSchema: <S extends AnySchema>(schema: S, value: unknown) => unknown;
47
+ declare const decodeWithSchema: <S extends AnySchema>(schema: S, value: unknown) => SchemaType<S>;
48
+ declare const encodeDynamicValue: (value: unknown, metadata: OpcuaDynamicValueMetadata) => unknown;
49
+ declare const decodeDynamicValue: (value: unknown, variant?: Variant) => OpcuaDynamicValue;
50
+ declare const makeVariantFromMetadata: (metadata: OpcuaDynamicValueMetadata, value: unknown) => Variant;
51
+ //#endregion
52
+ export { AnySchema, Codec, CodecMetadata, CodecType, OpcuaCodec, SchemaType, decodeDynamicValue, decodeWithSchema, dynamic, encodeDynamicValue, encodeWithSchema, makeVariantFromMetadata, schema, structure, structureArray };
53
+ //# sourceMappingURL=codec.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codec.d.mts","names":[],"sources":["../../../src/internal/values/codec.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;KA8BY,SAAA,GAAY,MAAA,CAAO;KACnB,qBAAqB,aAAa,MAAA,CAAO,MAAA,CAAO,KAAK;KAErD;;EAHA,SAAA,EAAA,CAAS,EAIyB,GAJzB;AACrB,CAAA,GAAY;EAAqB,SAAA,IAAA,EAAA,QAAA;EAAgC,SAAA,MAAA,EAIjB,SAJiB;EAAnB,SAAO,EAAO,CAAA,EAIa,GAJb;CAAI,GAK5D,YAL4D,CAK/C,GAL+C,CAAA,GAAA,CAAA,OAAA,SAM3C,GAN2C,GAOxD,iBAPwD,CAAA,OAAA,CAAA,GAQxD,GARwD,SAQ9C,aAR8C,CAAA,KAAA,KAAA,CAAA,GAStD,iBATsD,CASpC,IAToC,CAAA,GAAA,KAAA,CAAA;AAEpD,KAUA,SAVU,CAAA,CAAA,CAAA,GAWpB,CAXoB,SAWV,iBAXU,CAAA,KAAA,EAAA,CAAA,GAYhB,aAZgB,CAYF,CAZE,CAAA,GAahB,CAbgB,SAaN,UAbM,CAAA,KAAA,EAAA,CAAA,GAAA,CAAA,GAAA,KAAA;AACwB,KAgBlC,aAAA,GAhBkC;EACE,SAAA,MAAA,EAgB7B,YAhB6B;EAAyB,SAAA,SAAA,EAAA,MAAA;EACxD,SAAA,eAAA,CAAA,EAiBY,aAjBZ,CAAA,MAAA,CAAA;EAAb,SAAA,GAAA,EAAA;IACiB,SAAA,gBAAA,EAgBqB,WAAA,CAEU,MAlB/B;IACb,SAAA,eAAA,EAkBsB,QAlBtB;EACA,CAAA;CAAU;AACU,cAoBf,OApBe,EAAA,CAAA,MAoBA,iBApBA,CAAA,GAAA,GAoBsB,UApBtB,CAoBiC,GApBjC,CAAA;AAAlB,cAwBG,MAxBH,EAAA,CAAA,UAwBuB,SAxBvB,CAAA,CAAA,MAAA,EAyBA,CAzBA,EAAA,GA0BP,UA1BO,CA0BI,UA1BJ,CA0Be,CA1Bf,CAAA,CAAA;AAAiB,cA+Bd,SA/Bc,EAAA,CAAA,UA+BS,SA/BT,CAAA,CAAA,OAAA,EAAA;EAGf,SAAA,IAAS,EAAA,MAAA;EACnB,SAAA,UAAA,EA6BqB,YA7BrB;EAAU,SAAA,MAAA,EA8BO,CA9BP;CACQ,EAAA,GA8BhB,YA9BgB,CA8BH,UA9BG,CA8BQ,CA9BR,CAAA,CAAA;AAAd,cAqCO,cArCP,EAAA,CAAA,GAAA,CAAA,CAAA,SAAA,EAsCO,YAtCP,CAsCoB,GAtCpB,CAAA,EAAA,GAuCH,iBAvCG,CAuCe,GAvCf,CAAA;AACA,cA2CO,KA3CP,EAAA;EAAU,MAAA,EAAA,CAAA,GAAA,CAAA,CAAA,KAAA,EA6CL,UA7CK,CA6CM,GA7CN,CAAA,EAAA,KAAA,EA8CL,GA9CK,EAAA,QAAA,EA+CF,aA/CE,EAAA,gBAAA,EAgDM,qBAhDN,EAAA,GAgD2B,MAAA,CAAA,MAhD3B,CAgD2B,OAhD3B,EAgD2B,gBAAA,GAAA,iBAhD3B,EAAA,KAAA,CAAA;EAAU,MAAA,EAAA,CAAA,GAAA,CAAA,CAAA,KAAA,EAmDf,UAnDe,CAmDJ,GAnDI,CAAA,EAAA,OAAA,EAoDb,OApDa,GAAA,SAAA,EAAA,SAAA,EAqDX,SArDW,GAAA,SAAA,EAAA,gBAAA,EAsDJ,qBAtDI,EAAA,GAsDiB,MAAA,CAAA,MAtDjB,CAsDiB,GAtDjB,EAAA,OAAA,EAAA,KAAA,CAAA;EAId,gBAAa,EAAA,CAAA,KAAA,EAoDG,UApDH,CAAA,OAAA,CAAA,EAAA,QAAA,EAoDkC,aApDlC,EAAA,GAoD+C,MAAA,CAAA,MApD/C,CAAA,IAAA,EAoD+C,uBApD/C,EAAA,KAAA,CAAA;EACN,wBAAA,EAAA,CAAA,KAAA,EAqDiB,UArDjB,CAAA,OAAA,CAAA,EAAA,GAAA,KAAA,IAqDoC,YArDpC,CAAA,OAAA,CAAA,GAqDoC,iBArDpC,CAAA,OAAA,CAAA;CAEU;AAAa,cAuD7B,gBArDuC,EAAA,CAAA,UAqDT,SArDS,CAAA,CAAA,MAAA,EAsD1C,CAtD0C,EAAA,KAAA,EAAA,OAAA,EAAA,GAAA,OAAA;AACtB,cA0DjB,gBA1DiB,EAAA,CAAA,UA0Da,SA1Db,CAAA,CAAA,MAAA,EA2DpB,CA3DoB,EAAA,KAAA,EAAA,OAAA,EAAA,GA6D3B,UA7D2B,CA6DhB,CA7DgB,CAAA;AAAQ,cAkEzB,kBAlEyB,EAAA,CAAA,KAAA,EAAA,OAAA,EAAA,QAAA,EAoE1B,yBApE0B,EAAA,GAAA,OAAA;AAIzB,cAmEA,kBAjEX,EAAA,CAAA,KAAA,EAAA,OAAA,EAAA,OAAA,CAAA,EAmEU,OAnEV,EAAA,GAoEC,iBApED;AAF0B,cAwEf,uBAxEe,EAAA,CAAA,QAAA,EAyEhB,yBAzEgB,EAAA,KAAA,EAAA,OAAA,EAAA,GA0EZ,OA1EY"}
@@ -0,0 +1,117 @@
1
+ import { denormalizeDynamicValue, isArrayRank, normalizeDynamicValue, plainVariantValue } from "./normalize.mjs";
2
+ import { encodeError } from "../../OpcuaError.mjs";
3
+ import { isStructureArrayDef } from "../structures/model.mjs";
4
+ import { validateStructureMetadata } from "../structures/runtime.mjs";
5
+ import { DataType, Variant, VariantArrayType } from "node-opcua";
6
+ import { Effect, Schema } from "effect";
7
+
8
+ //#region src/internal/values/codec.ts
9
+ const dynamic = () => ({ _tag: "Dynamic" });
10
+ const schema = (schema$1) => ({
11
+ _tag: "Schema",
12
+ schema: schema$1
13
+ });
14
+ const structure = (options) => ({
15
+ _tag: "Structure",
16
+ name: options.name,
17
+ dataTypeId: options.dataTypeId,
18
+ schema: options.schema
19
+ });
20
+ const structureArray = (structure$1) => ({
21
+ _tag: "StructureArray",
22
+ item: structure$1
23
+ });
24
+ const Codec = {
25
+ encode: (codec, value, metadata, structureRuntime) => encodeCodec(codec, value, metadata, structureRuntime),
26
+ decode: (codec, variant, dataValue, structureRuntime) => decodeCodec(codec, variant, dataValue, structureRuntime),
27
+ validateMetadata: (codec, metadata) => validateCodecMetadata(codec, metadata),
28
+ requiresStructureRuntime: (codec) => codec._tag === "Structure" || codec._tag === "StructureArray"
29
+ };
30
+ const encodeWithSchema = (schema$1, value) => Schema.encodeUnknownSync(schema$1)(value);
31
+ const decodeWithSchema = (schema$1, value) => Schema.decodeUnknownSync(schema$1)(value);
32
+ const encodeDynamicValue = (value, metadata) => denormalizeDynamicValue(value, metadata);
33
+ const decodeDynamicValue = (value, variant) => normalizeDynamicValue(value, variant);
34
+ const makeVariantFromMetadata = (metadata, value) => new Variant({
35
+ dataType: metadata.raw.dataType,
36
+ arrayType: variantArrayType(metadata, value),
37
+ dimensions: variantArrayType(metadata, value) === VariantArrayType.Matrix ? matrixDimensions(metadata, value) : void 0,
38
+ value: flattenMatrixValue(metadata, value)
39
+ });
40
+ const variantArrayType = (metadata, value) => metadata.valueRank > 1 ? VariantArrayType.Matrix : Array.isArray(value) || isArrayRank(metadata.valueRank) ? VariantArrayType.Array : VariantArrayType.Scalar;
41
+ const flattenMatrixValue = (metadata, value) => {
42
+ if (metadata.valueRank <= 1 || !Array.isArray(value)) return value;
43
+ return value.flat(metadata.valueRank - 1);
44
+ };
45
+ const matrixDimensions = (metadata, value) => {
46
+ if (metadata.arrayDimensions && metadata.arrayDimensions.length > 0) return [...metadata.arrayDimensions];
47
+ return inferArrayDimensions(value, metadata.valueRank);
48
+ };
49
+ const inferArrayDimensions = (value, rank) => {
50
+ const dimensions = [];
51
+ let current = value;
52
+ for (let depth = 0; depth < rank; depth++) {
53
+ if (!Array.isArray(current)) return void 0;
54
+ dimensions.push(current.length);
55
+ current = current[0];
56
+ }
57
+ return dimensions;
58
+ };
59
+ const encodeCodec = (codec, value, metadata, structureRuntime) => {
60
+ switch (codec._tag) {
61
+ case "Dynamic": return Effect.suspend(() => {
62
+ try {
63
+ return Effect.succeed(makeVariantFromMetadata(codecMetadata(metadata), encodeDynamicValue(value, codecMetadata(metadata))));
64
+ } catch (error) {
65
+ return Effect.fail(encodeError({
66
+ nodeId: metadata.nodeId,
67
+ value,
68
+ error
69
+ }));
70
+ }
71
+ });
72
+ case "Schema": return Effect.try({
73
+ try: () => makeVariantFromMetadata(codecMetadata(metadata), encodeWithSchema(codec.schema, value)),
74
+ catch: (error) => encodeError({
75
+ nodeId: metadata.nodeId,
76
+ value,
77
+ error
78
+ })
79
+ });
80
+ case "Structure": return structureRuntime.variantFromStructure(metadata.nodeId, codec, value);
81
+ case "StructureArray": return structureRuntime.variantFromStructure(metadata.nodeId, codec, value);
82
+ }
83
+ };
84
+ const decodeCodec = (codec, variant, _dataValue, structureRuntime) => Effect.try({
85
+ try: () => {
86
+ switch (codec._tag) {
87
+ case "Dynamic": return decodeDynamicValue(variant?.value, variant);
88
+ case "Schema": return decodeWithSchema(codec.schema, plainVariantValue(variant?.value));
89
+ case "Structure": return decodeStructureValue(codec, variant, structureRuntime);
90
+ case "StructureArray": return decodeStructureValue(codec, variant, structureRuntime);
91
+ }
92
+ },
93
+ catch: (error) => error
94
+ });
95
+ const decodeStructureValue = (structure$1, variant, structureRuntime) => {
96
+ if (variant?.dataType !== DataType.ExtensionObject) throw new TypeError("Expected ExtensionObject Variant");
97
+ if (isStructureArrayDef(structure$1)) {
98
+ if (variant.arrayType !== VariantArrayType.Array) throw new TypeError("Expected ExtensionObject array Variant");
99
+ return structureRuntime.decodeStructureArray(structure$1, variant.value);
100
+ }
101
+ if (variant.arrayType !== VariantArrayType.Scalar) throw new TypeError("Expected scalar ExtensionObject Variant");
102
+ return structureRuntime.decodeStructure(structure$1, variant.value);
103
+ };
104
+ const validateCodecMetadata = (codec, metadata) => {
105
+ if (codec._tag !== "Structure" && codec._tag !== "StructureArray") return Effect.void;
106
+ const error = validateStructureMetadata("codec.structure", metadata.nodeId, metadata, codec);
107
+ return error ? Effect.fail(error) : Effect.void;
108
+ };
109
+ const codecMetadata = (metadata) => ({
110
+ raw: { dataType: metadata.raw.builtInDataType },
111
+ valueRank: metadata.valueRank,
112
+ arrayDimensions: metadata.arrayDimensions
113
+ });
114
+
115
+ //#endregion
116
+ export { Codec, decodeDynamicValue, decodeWithSchema, dynamic, encodeDynamicValue, encodeWithSchema, makeVariantFromMetadata, schema, structure, structureArray };
117
+ //# sourceMappingURL=codec.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codec.mjs","names":["structure","schema","dimensions: Array<number>"],"sources":["../../../src/internal/values/codec.ts"],"sourcesContent":["import {\n DataType,\n Variant,\n VariantArrayType,\n type DataValue,\n} from \"node-opcua\";\nimport { Effect, Schema } from \"effect\";\n\nimport {\n denormalizeDynamicValue,\n isArrayRank,\n normalizeDynamicValue,\n plainVariantValue,\n type OpcuaDynamicValue,\n type OpcuaDynamicValueMetadata,\n} from \"./normalize.js\";\nimport { encodeError, type OpcuaConfigurationError } from \"../../OpcuaError.js\";\nimport {\n validateStructureMetadata,\n type OpcuaStructureRuntime,\n} from \"../structures/runtime.js\";\nimport {\n isStructureArrayDef,\n type AnyStructureDef,\n type StructureArrayDef,\n type StructureDef,\n} from \"../structures/model.js\";\nimport type { NodeIdString } from \"../common/node-id.js\";\n\n// Sync encode/decode helpers only support schemas without contextual services.\nexport type AnySchema = Schema.Codec<unknown, unknown, never, never>;\nexport type SchemaType<S extends AnySchema> = Schema.Schema.Type<S>;\n\nexport type OpcuaCodec<A> =\n | { readonly _tag: \"Dynamic\"; readonly _A?: A }\n | { readonly _tag: \"Schema\"; readonly schema: AnySchema; readonly _A?: A }\n | StructureDef<A>\n | (unknown extends A\n ? StructureArrayDef<unknown>\n : A extends ReadonlyArray<infer Item>\n ? StructureArrayDef<Item>\n : never);\n\nexport type CodecType<C> =\n C extends StructureArrayDef<infer A>\n ? ReadonlyArray<A>\n : C extends OpcuaCodec<infer A>\n ? A\n : never;\n\nexport type CodecMetadata = {\n readonly nodeId: NodeIdString;\n readonly valueRank: number;\n readonly arrayDimensions?: ReadonlyArray<number>;\n readonly raw: {\n readonly declaredDataType: import(\"node-opcua\").NodeId;\n readonly builtInDataType: DataType;\n };\n};\n\nexport const dynamic = <A = OpcuaDynamicValue>(): OpcuaCodec<A> => ({\n _tag: \"Dynamic\",\n});\n\nexport const schema = <S extends AnySchema>(\n schema: S,\n): OpcuaCodec<SchemaType<S>> => ({\n _tag: \"Schema\",\n schema,\n});\n\nexport const structure = <S extends AnySchema>(options: {\n readonly name: string;\n readonly dataTypeId: NodeIdString;\n readonly schema: S;\n}): StructureDef<SchemaType<S>> => ({\n _tag: \"Structure\",\n name: options.name,\n dataTypeId: options.dataTypeId,\n schema: options.schema as Schema.Codec<unknown, SchemaType<S>, never, never>,\n});\n\nexport const structureArray = <A>(\n structure: StructureDef<A>,\n): StructureArrayDef<A> => ({\n _tag: \"StructureArray\",\n item: structure,\n});\n\nexport const Codec = {\n encode: <A>(\n codec: OpcuaCodec<A>,\n value: A,\n metadata: CodecMetadata,\n structureRuntime: OpcuaStructureRuntime,\n ) => encodeCodec(codec, value, metadata, structureRuntime),\n decode: <A>(\n codec: OpcuaCodec<A>,\n variant: Variant | undefined,\n dataValue: DataValue | undefined,\n structureRuntime: OpcuaStructureRuntime,\n ) => decodeCodec(codec, variant, dataValue, structureRuntime),\n validateMetadata: (codec: OpcuaCodec<unknown>, metadata: CodecMetadata) =>\n validateCodecMetadata(codec, metadata),\n requiresStructureRuntime: (codec: OpcuaCodec<unknown>) =>\n codec._tag === \"Structure\" || codec._tag === \"StructureArray\",\n};\n\nexport const encodeWithSchema = <S extends AnySchema>(\n schema: S,\n value: unknown,\n): unknown =>\n Schema.encodeUnknownSync(schema as unknown as Schema.Encoder<unknown>)(value);\n\nexport const decodeWithSchema = <S extends AnySchema>(\n schema: S,\n value: unknown,\n): SchemaType<S> =>\n Schema.decodeUnknownSync(schema as unknown as Schema.Decoder<unknown>)(\n value,\n ) as SchemaType<S>;\n\nexport const encodeDynamicValue = (\n value: unknown,\n metadata: OpcuaDynamicValueMetadata,\n): unknown => denormalizeDynamicValue(value, metadata);\n\nexport const decodeDynamicValue = (\n value: unknown,\n variant?: Variant,\n): OpcuaDynamicValue => normalizeDynamicValue(value, variant);\n\nexport const makeVariantFromMetadata = (\n metadata: OpcuaDynamicValueMetadata,\n value: unknown,\n) =>\n new Variant({\n dataType: metadata.raw.dataType,\n arrayType: variantArrayType(metadata, value),\n dimensions:\n variantArrayType(metadata, value) === VariantArrayType.Matrix\n ? matrixDimensions(metadata, value)\n : undefined,\n value: flattenMatrixValue(metadata, value) as Variant[\"value\"],\n });\n\nconst variantArrayType = (\n metadata: OpcuaDynamicValueMetadata,\n value: unknown,\n) =>\n metadata.valueRank > 1\n ? VariantArrayType.Matrix\n : Array.isArray(value) || isArrayRank(metadata.valueRank)\n ? VariantArrayType.Array\n : VariantArrayType.Scalar;\n\nconst flattenMatrixValue = (\n metadata: OpcuaDynamicValueMetadata,\n value: unknown,\n): unknown => {\n if (metadata.valueRank <= 1 || !Array.isArray(value)) return value;\n return value.flat(metadata.valueRank - 1);\n};\n\nconst matrixDimensions = (\n metadata: OpcuaDynamicValueMetadata,\n value: unknown,\n): Array<number> | undefined => {\n if (metadata.arrayDimensions && metadata.arrayDimensions.length > 0) {\n return [...metadata.arrayDimensions];\n }\n return inferArrayDimensions(value, metadata.valueRank);\n};\n\nconst inferArrayDimensions = (\n value: unknown,\n rank: number,\n): Array<number> | undefined => {\n const dimensions: Array<number> = [];\n let current = value;\n for (let depth = 0; depth < rank; depth++) {\n if (!Array.isArray(current)) return undefined;\n dimensions.push(current.length);\n current = current[0];\n }\n return dimensions;\n};\n\nconst encodeCodec = <A>(\n codec: OpcuaCodec<A>,\n value: A,\n metadata: CodecMetadata,\n structureRuntime: OpcuaStructureRuntime,\n) => {\n switch (codec._tag) {\n case \"Dynamic\":\n return Effect.suspend(() => {\n try {\n return Effect.succeed(\n makeVariantFromMetadata(\n codecMetadata(metadata),\n encodeDynamicValue(value, codecMetadata(metadata)),\n ),\n );\n } catch (error) {\n return Effect.fail(\n encodeError({ nodeId: metadata.nodeId, value, error }),\n );\n }\n });\n case \"Schema\":\n return Effect.try({\n try: () =>\n makeVariantFromMetadata(\n codecMetadata(metadata),\n encodeWithSchema(codec.schema, value),\n ),\n catch: (error) =>\n encodeError({ nodeId: metadata.nodeId, value, error }),\n });\n case \"Structure\":\n return structureRuntime.variantFromStructure(\n metadata.nodeId,\n codec,\n value,\n );\n case \"StructureArray\":\n return structureRuntime.variantFromStructure(\n metadata.nodeId,\n codec,\n value,\n );\n }\n};\n\nconst decodeCodec = <A>(\n codec: OpcuaCodec<A>,\n variant: Variant | undefined,\n _dataValue: DataValue | undefined,\n structureRuntime: OpcuaStructureRuntime,\n): Effect.Effect<A, unknown> =>\n Effect.try({\n try: () => {\n switch (codec._tag) {\n case \"Dynamic\":\n return decodeDynamicValue(variant?.value, variant) as A;\n case \"Schema\":\n return decodeWithSchema(\n codec.schema,\n plainVariantValue(variant?.value),\n ) as A;\n case \"Structure\":\n return decodeStructureValue(codec, variant, structureRuntime) as A;\n case \"StructureArray\":\n return decodeStructureValue(codec, variant, structureRuntime) as A;\n }\n },\n catch: (error) => error,\n });\n\nconst decodeStructureValue = (\n structure: AnyStructureDef,\n variant: Variant | undefined,\n structureRuntime: OpcuaStructureRuntime,\n) => {\n if (variant?.dataType !== DataType.ExtensionObject) {\n throw new TypeError(\"Expected ExtensionObject Variant\");\n }\n if (isStructureArrayDef(structure)) {\n if (variant.arrayType !== VariantArrayType.Array) {\n throw new TypeError(\"Expected ExtensionObject array Variant\");\n }\n return structureRuntime.decodeStructureArray(structure, variant.value);\n }\n if (variant.arrayType !== VariantArrayType.Scalar) {\n throw new TypeError(\"Expected scalar ExtensionObject Variant\");\n }\n return structureRuntime.decodeStructure(structure, variant.value);\n};\n\nconst validateCodecMetadata = (\n codec: OpcuaCodec<unknown>,\n metadata: CodecMetadata,\n): Effect.Effect<void, OpcuaConfigurationError> => {\n if (codec._tag !== \"Structure\" && codec._tag !== \"StructureArray\") {\n return Effect.void;\n }\n const error = validateStructureMetadata(\n \"codec.structure\",\n metadata.nodeId,\n metadata,\n codec,\n );\n return error ? Effect.fail(error) : Effect.void;\n};\n\nconst codecMetadata = (metadata: CodecMetadata): OpcuaDynamicValueMetadata => ({\n raw: { dataType: metadata.raw.builtInDataType },\n valueRank: metadata.valueRank,\n arrayDimensions: metadata.arrayDimensions,\n});\n"],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { OpcuaDynamicValue, OpcuaExpandedNodeIdInfo, OpcuaLocalizedTextInfo, OpcuaNodeIdInfo, OpcuaQualifiedNameInfo, OpcuaStatusInfo, OpcuaVariantInfo } from "../../OpcuaVariable.mjs";
2
+ import { DataType, ExpandedNodeId, NodeId, StatusCode, Variant } from "node-opcua";
3
+
4
+ //#region src/internal/values/normalize.d.ts
5
+ declare const normalizeNodeId: (nodeId: NodeId) => OpcuaNodeIdInfo;
6
+ declare const normalizeExpandedNodeId: (nodeId: ExpandedNodeId) => OpcuaExpandedNodeIdInfo;
7
+ declare const normalizeQualifiedName: (name: {
8
+ readonly namespaceIndex?: number;
9
+ readonly name?: string | null;
10
+ readonly toString: () => string;
11
+ }) => OpcuaQualifiedNameInfo;
12
+ declare const normalizeLocalizedText: (text: {
13
+ readonly text?: string | null;
14
+ readonly locale?: string | null;
15
+ }) => OpcuaLocalizedTextInfo;
16
+ declare const normalizeStatusCode: (statusCode: StatusCode) => OpcuaStatusInfo;
17
+ declare const normalizeVariantInfo: (variant: Variant) => OpcuaVariantInfo;
18
+ declare const normalizeDynamicValue: (value: unknown, variant?: Variant) => OpcuaDynamicValue;
19
+ declare const plainVariantValue: (value: unknown) => unknown;
20
+ type OpcuaDynamicValueMetadata = {
21
+ readonly raw: {
22
+ readonly dataType: DataType;
23
+ };
24
+ readonly valueRank: number;
25
+ readonly arrayDimensions?: ReadonlyArray<number>;
26
+ };
27
+ declare const denormalizeDynamicValue: (value: unknown, metadata?: OpcuaDynamicValueMetadata) => unknown;
28
+ declare const normalizeTimestamp: (timestamp: Date | null | undefined) => string | undefined;
29
+ declare const isGood: (statusCode: StatusCode) => boolean;
30
+ declare const isArrayRank: (valueRank: number) => boolean;
31
+ //#endregion
32
+ export { type OpcuaDynamicValue, OpcuaDynamicValueMetadata, type OpcuaExpandedNodeIdInfo, type OpcuaLocalizedTextInfo, type OpcuaNodeIdInfo, type OpcuaQualifiedNameInfo, type OpcuaStatusInfo, type OpcuaVariantInfo, denormalizeDynamicValue, isArrayRank, isGood, normalizeDynamicValue, normalizeExpandedNodeId, normalizeLocalizedText, normalizeNodeId, normalizeQualifiedName, normalizeStatusCode, normalizeTimestamp, normalizeVariantInfo, plainVariantValue };
33
+ //# sourceMappingURL=normalize.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.mts","names":[],"sources":["../../../src/internal/values/normalize.ts"],"sourcesContent":[],"mappings":";;;;cAoCa,0BAA2B,WAAS;AAApC,cAOA,uBAPoC,EAAA,CAAA,MAAA,EAQvC,cAHR,EAAA,GAIC,uBAJD;AAEW,cAgBA,sBAfH,EAAA,CAAA,IAAA,EAAA;EAeG,SAAA,cAAA,CAAA,EAQX,MAAA;EAEW,SAAA,IAAA,CAAA,EAAA,MAAA,GAMX,IAAA;EAEW,SAAA,QAAA,EAAA,GAQX,GAAA,MAAA;AAEF,CAAA,EAAA,GAxBI,sBA+BF;AAEW,cA3BA,sBA6BD,EAAA,CAAA,IACT,EAAA;EAmGU,SAAA,IAAA,CAAA,EAAA,MAKF,GAAA,IAAA;EAmBC,SAAA,MAAA,CAAA,EAAA,MAAA,GAAA,IAAyB;AAerC,CAAA,EAAA,GArKI,sBAqKS;AA+EA,cA/OA,mBA+OiC,EAAI,CAAA,UAAA,EA9OpC,UA8OoC,EAAA,GA7O/C,eA6O+C;AAErC,cAvOA,oBAuOgC,EAAA,CAAA,OAAA,EAvOC,OAuOD,EAAA,GAvOW,gBAuOX;AAChC,cA/NA,qBA+NmD,EAAA,CAAA,KAAA,EAAA,OAAA,EAAA,OAAA,CAAA,EA7NpD,OA6NoD,EAAA,GA5N7D,iBA4N6D;cAzHnD;KAwBD,yBAAA;;uBAEW;;;6BAGM;;cAUhB,qDAEA;cA6EA,gCAAiC;cAEjC,qBAAsB;cACtB"}
@@ -0,0 +1,177 @@
1
+ import { extensionObjectBody, extensionObjectTypeName, isNodeOpcuaExtensionObject } from "../structures/adapter.mjs";
2
+ import { DataType, LocalizedText, NodeId, QualifiedName, VariantArrayType, coerceNodeId } from "node-opcua";
3
+
4
+ //#region src/internal/values/normalize.ts
5
+ const normalizeNodeId = (nodeId) => ({
6
+ text: nodeId.toString(),
7
+ namespace: nodeId.namespace,
8
+ value: nodeId.value,
9
+ identifierType: String(nodeId.identifierType)
10
+ });
11
+ const normalizeExpandedNodeId = (nodeId) => {
12
+ const isRemote = Boolean(nodeId.namespaceUri) || Boolean(nodeId.serverIndex);
13
+ return {
14
+ text: nodeId.toString(),
15
+ namespace: nodeId.namespace,
16
+ value: nodeId.value,
17
+ identifierType: String(nodeId.identifierType),
18
+ namespaceUri: nodeId.namespaceUri ?? void 0,
19
+ serverIndex: nodeId.serverIndex || void 0,
20
+ isLocal: !isRemote,
21
+ isRemote
22
+ };
23
+ };
24
+ const normalizeQualifiedName = (name) => ({
25
+ namespaceIndex: name.namespaceIndex ?? 0,
26
+ name: name.name ?? "",
27
+ text: name.toString()
28
+ });
29
+ const normalizeLocalizedText = (text) => ({
30
+ text: text.text ?? "",
31
+ locale: text.locale ?? void 0
32
+ });
33
+ const normalizeStatusCode = (statusCode) => ({
34
+ text: statusCode.toString(),
35
+ code: statusCode.value,
36
+ isGood: statusCode.isGood(),
37
+ isUncertain: !statusCode.isGood() && !statusCode.isBad(),
38
+ isBad: statusCode.isBad()
39
+ });
40
+ const normalizeVariantInfo = (variant) => ({
41
+ dataType: DataType[variant.dataType] ?? String(variant.dataType),
42
+ arrayType: VariantArrayType[variant.arrayType],
43
+ arrayDimensions: variant.dimensions ?? void 0
44
+ });
45
+ const normalizeDynamicValue = (value, variant) => {
46
+ if (variant && variant.arrayType !== VariantArrayType.Scalar && !isByteStringValue(value)) {
47
+ const elements = arrayElements(value);
48
+ if (elements) return elements.map((element) => normalizeElement(element, variant.dataType));
49
+ }
50
+ return normalizeElement(value, variant?.dataType);
51
+ };
52
+ const normalizeElement = (value, dataType) => {
53
+ if (value === null || value === void 0) return null;
54
+ if (dataType === DataType.Int64 || dataType === DataType.UInt64) {
55
+ const text = int64Text(value, dataType === DataType.Int64);
56
+ if (text !== void 0) return dataType === DataType.UInt64 ? {
57
+ _tag: "UInt64",
58
+ text
59
+ } : {
60
+ _tag: "Int64",
61
+ text
62
+ };
63
+ }
64
+ if (isByteStringValue(value)) return {
65
+ _tag: "ByteString",
66
+ base64: Buffer.from(value).toString("base64")
67
+ };
68
+ const elements = arrayElements(value);
69
+ if (elements) return elements.map((element) => normalizeElement(element));
70
+ if (value instanceof Date) return {
71
+ _tag: "DateTime",
72
+ iso: value.toISOString()
73
+ };
74
+ if (value instanceof NodeId) return {
75
+ _tag: "NodeId",
76
+ ...normalizeNodeId(value)
77
+ };
78
+ if (typeof value === "bigint") return {
79
+ _tag: "Int64",
80
+ text: value.toString()
81
+ };
82
+ if (typeof value === "boolean" || typeof value === "number" || typeof value === "string") return value;
83
+ if (value instanceof LocalizedText) return {
84
+ _tag: "LocalizedText",
85
+ text: value.text ?? "",
86
+ locale: value.locale ?? void 0
87
+ };
88
+ if (value instanceof QualifiedName) return {
89
+ _tag: "QualifiedName",
90
+ namespaceIndex: value.namespaceIndex ?? 0,
91
+ name: value.name ?? "",
92
+ text: value.toString()
93
+ };
94
+ if (isNodeOpcuaExtensionObject(value)) return {
95
+ _tag: "ExtensionObject",
96
+ typeName: extensionObjectTypeName(value),
97
+ value: normalizePlainObject(extensionObjectBody(value))
98
+ };
99
+ if (typeof value === "object") return {
100
+ _tag: "Object",
101
+ typeName: objectTypeName(value),
102
+ value: normalizePlainObject(value)
103
+ };
104
+ return String(value);
105
+ };
106
+ const isByteStringValue = (value) => Buffer.isBuffer(value) || value instanceof Uint8Array;
107
+ const arrayElements = (value) => {
108
+ if (Array.isArray(value)) return value;
109
+ if (ArrayBuffer.isView(value) && !(value instanceof DataView)) return Array.from(value);
110
+ };
111
+ const plainVariantValue = (value) => !isByteStringValue(value) && ArrayBuffer.isView(value) && !(value instanceof DataView) ? Array.from(value) : value;
112
+ const int64Text = (value, signed) => {
113
+ if (typeof value === "bigint") return value.toString();
114
+ if (typeof value === "number") return String(value);
115
+ if (typeof value === "string") return value;
116
+ if (Array.isArray(value) && value.length === 2 && typeof value[0] === "number" && typeof value[1] === "number") {
117
+ const unsigned = BigInt(value[0] >>> 0) << 32n | BigInt(value[1] >>> 0);
118
+ return (signed ? BigInt.asIntN(64, unsigned) : unsigned).toString();
119
+ }
120
+ };
121
+ const normalizePlainObject = (record) => Object.fromEntries(Object.entries(record).filter(([key]) => !key.startsWith("_")).map(([key, value]) => [key, normalizeDynamicValue(value)]));
122
+ const denormalizeDynamicValue = (value, metadata) => {
123
+ if (Array.isArray(value)) return value.map((item) => denormalizeDynamicValue(item, metadata));
124
+ if (!value || typeof value !== "object") return value;
125
+ switch (value._tag) {
126
+ case "DateTime":
127
+ assertDynamicDataType(value, metadata, DataType.DateTime);
128
+ return new Date(value.iso);
129
+ case "ByteString":
130
+ assertDynamicDataType(value, metadata, DataType.ByteString);
131
+ return Buffer.from(value.base64, "base64");
132
+ case "Int64":
133
+ assertDynamicDataType(value, metadata, DataType.Int64);
134
+ return value.text;
135
+ case "UInt64":
136
+ assertDynamicDataType(value, metadata, DataType.UInt64);
137
+ return value.text;
138
+ case "NodeId":
139
+ assertDynamicDataType(value, metadata, DataType.NodeId);
140
+ return coerceNodeId(value.text);
141
+ case "LocalizedText": {
142
+ assertDynamicDataType(value, metadata, DataType.LocalizedText);
143
+ const text = value;
144
+ return new LocalizedText({
145
+ text: text.text,
146
+ locale: text.locale
147
+ });
148
+ }
149
+ case "QualifiedName": {
150
+ assertDynamicDataType(value, metadata, DataType.QualifiedName);
151
+ const name = value;
152
+ return new QualifiedName({
153
+ namespaceIndex: name.namespaceIndex,
154
+ name: name.name
155
+ });
156
+ }
157
+ case "ExtensionObject": throw new TypeError("ExtensionObject dynamic writes require a schema");
158
+ case "Object": throw new TypeError("Object dynamic writes require a schema");
159
+ default:
160
+ if (metadata?.raw.dataType === DataType.ExtensionObject && value !== null && value !== void 0) throw new TypeError("ExtensionObject dynamic writes require a schema");
161
+ return value;
162
+ }
163
+ };
164
+ const objectTypeName = (value) => {
165
+ const name = value.constructor?.name;
166
+ return name && name !== "Object" ? name : void 0;
167
+ };
168
+ const assertDynamicDataType = (value, metadata, expected) => {
169
+ if (metadata && metadata.raw.dataType !== expected) throw new TypeError(`Cannot write ${value._tag ?? "value"} to DataType.${DataType[metadata.raw.dataType]}`);
170
+ };
171
+ const normalizeTimestamp = (timestamp) => timestamp instanceof Date ? timestamp.toISOString() : void 0;
172
+ const isGood = (statusCode) => statusCode.isGood();
173
+ const isArrayRank = (valueRank) => valueRank >= 1;
174
+
175
+ //#endregion
176
+ export { denormalizeDynamicValue, isArrayRank, isGood, normalizeDynamicValue, normalizeExpandedNodeId, normalizeLocalizedText, normalizeNodeId, normalizeQualifiedName, normalizeStatusCode, normalizeTimestamp, normalizeVariantInfo, plainVariantValue };
177
+ //# sourceMappingURL=normalize.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.mjs","names":[],"sources":["../../../src/internal/values/normalize.ts"],"sourcesContent":["import {\n coerceNodeId,\n DataType,\n LocalizedText,\n NodeId,\n QualifiedName,\n VariantArrayType,\n type ExpandedNodeId,\n type StatusCode,\n type Variant,\n} from \"node-opcua\";\n\nimport {\n extensionObjectBody,\n extensionObjectTypeName,\n isNodeOpcuaExtensionObject,\n} from \"../structures/adapter.js\";\nimport type {\n OpcuaDynamicValue,\n OpcuaExpandedNodeIdInfo,\n OpcuaLocalizedTextInfo,\n OpcuaNodeIdInfo,\n OpcuaQualifiedNameInfo,\n OpcuaStatusInfo,\n OpcuaVariantInfo,\n} from \"../../OpcuaVariable.js\";\nexport type {\n OpcuaDynamicValue,\n OpcuaExpandedNodeIdInfo,\n OpcuaLocalizedTextInfo,\n OpcuaNodeIdInfo,\n OpcuaQualifiedNameInfo,\n OpcuaStatusInfo,\n OpcuaVariantInfo,\n} from \"../../OpcuaVariable.js\";\n\nexport const normalizeNodeId = (nodeId: NodeId): OpcuaNodeIdInfo => ({\n text: nodeId.toString(),\n namespace: nodeId.namespace,\n value: nodeId.value,\n identifierType: String(nodeId.identifierType),\n});\n\nexport const normalizeExpandedNodeId = (\n nodeId: ExpandedNodeId,\n): OpcuaExpandedNodeIdInfo => {\n const isRemote = Boolean(nodeId.namespaceUri) || Boolean(nodeId.serverIndex);\n return {\n text: nodeId.toString(),\n namespace: nodeId.namespace,\n value: nodeId.value,\n identifierType: String(nodeId.identifierType),\n namespaceUri: nodeId.namespaceUri ?? undefined,\n serverIndex: nodeId.serverIndex || undefined,\n isLocal: !isRemote,\n isRemote,\n };\n};\n\nexport const normalizeQualifiedName = (name: {\n readonly namespaceIndex?: number;\n readonly name?: string | null;\n readonly toString: () => string;\n}): OpcuaQualifiedNameInfo => ({\n namespaceIndex: name.namespaceIndex ?? 0,\n name: name.name ?? \"\",\n text: name.toString(),\n});\n\nexport const normalizeLocalizedText = (text: {\n readonly text?: string | null;\n readonly locale?: string | null;\n}): OpcuaLocalizedTextInfo => ({\n text: text.text ?? \"\",\n locale: text.locale ?? undefined,\n});\n\nexport const normalizeStatusCode = (\n statusCode: StatusCode,\n): OpcuaStatusInfo => ({\n text: statusCode.toString(),\n code: statusCode.value,\n isGood: statusCode.isGood(),\n isUncertain: !statusCode.isGood() && !statusCode.isBad(),\n isBad: statusCode.isBad(),\n});\n\nexport const normalizeVariantInfo = (variant: Variant): OpcuaVariantInfo => ({\n dataType: DataType[variant.dataType] ?? String(variant.dataType),\n arrayType: VariantArrayType[variant.arrayType] as\n | \"Scalar\"\n | \"Array\"\n | \"Matrix\",\n arrayDimensions: variant.dimensions ?? undefined,\n});\n\nexport const normalizeDynamicValue = (\n value: unknown,\n variant?: Variant,\n): OpcuaDynamicValue => {\n if (\n variant &&\n variant.arrayType !== VariantArrayType.Scalar &&\n !isByteStringValue(value)\n ) {\n const elements = arrayElements(value);\n if (elements) {\n return elements.map((element) =>\n normalizeElement(element, variant.dataType),\n );\n }\n }\n return normalizeElement(value, variant?.dataType);\n};\n\nconst normalizeElement = (\n value: unknown,\n dataType?: DataType,\n): OpcuaDynamicValue => {\n if (value === null || value === undefined) return null;\n if (dataType === DataType.Int64 || dataType === DataType.UInt64) {\n const text = int64Text(value, dataType === DataType.Int64);\n if (text !== undefined) {\n return dataType === DataType.UInt64\n ? { _tag: \"UInt64\", text }\n : { _tag: \"Int64\", text };\n }\n }\n if (isByteStringValue(value)) {\n return {\n _tag: \"ByteString\",\n base64: Buffer.from(value).toString(\"base64\"),\n };\n }\n const elements = arrayElements(value);\n if (elements) {\n return elements.map((element) => normalizeElement(element));\n }\n if (value instanceof Date) {\n return { _tag: \"DateTime\", iso: value.toISOString() };\n }\n if (value instanceof NodeId) {\n return { _tag: \"NodeId\", ...normalizeNodeId(value) };\n }\n if (typeof value === \"bigint\") {\n return { _tag: \"Int64\", text: value.toString() };\n }\n if (\n typeof value === \"boolean\" ||\n typeof value === \"number\" ||\n typeof value === \"string\"\n ) {\n return value;\n }\n if (value instanceof LocalizedText) {\n return {\n _tag: \"LocalizedText\",\n text: value.text ?? \"\",\n locale: value.locale ?? undefined,\n };\n }\n if (value instanceof QualifiedName) {\n return {\n _tag: \"QualifiedName\",\n namespaceIndex: value.namespaceIndex ?? 0,\n name: value.name ?? \"\",\n text: value.toString(),\n };\n }\n if (isNodeOpcuaExtensionObject(value)) {\n return {\n _tag: \"ExtensionObject\",\n typeName: extensionObjectTypeName(value),\n value: normalizePlainObject(extensionObjectBody(value)),\n };\n }\n if (typeof value === \"object\") {\n return {\n _tag: \"Object\",\n typeName: objectTypeName(value),\n value: normalizePlainObject(value as Record<string, unknown>),\n };\n }\n return String(value);\n};\n\nconst isByteStringValue = (value: unknown): value is Uint8Array =>\n Buffer.isBuffer(value) || value instanceof Uint8Array;\n\n// node-opcua materializes numeric array variants as typed arrays.\nconst arrayElements = (value: unknown): ReadonlyArray<unknown> | undefined => {\n if (Array.isArray(value)) return value;\n if (ArrayBuffer.isView(value) && !(value instanceof DataView)) {\n return Array.from(value as unknown as ArrayLike<unknown>);\n }\n return undefined;\n};\n\nexport const plainVariantValue = (value: unknown): unknown =>\n !isByteStringValue(value) &&\n ArrayBuffer.isView(value) &&\n !(value instanceof DataView)\n ? Array.from(value as unknown as ArrayLike<unknown>)\n : value;\n\n// node-opcua represents Int64/UInt64 values as [high, low] UInt32 pairs.\nconst int64Text = (value: unknown, signed: boolean): string | undefined => {\n if (typeof value === \"bigint\") return value.toString();\n if (typeof value === \"number\") return String(value);\n if (typeof value === \"string\") return value;\n if (\n Array.isArray(value) &&\n value.length === 2 &&\n typeof value[0] === \"number\" &&\n typeof value[1] === \"number\"\n ) {\n const unsigned = (BigInt(value[0] >>> 0) << 32n) | BigInt(value[1] >>> 0);\n return (signed ? BigInt.asIntN(64, unsigned) : unsigned).toString();\n }\n return undefined;\n};\n\nexport type OpcuaDynamicValueMetadata = {\n readonly raw: {\n readonly dataType: DataType;\n };\n readonly valueRank: number;\n readonly arrayDimensions?: ReadonlyArray<number>;\n};\n\nconst normalizePlainObject = (record: Record<string, unknown>) =>\n Object.fromEntries(\n Object.entries(record)\n .filter(([key]) => !key.startsWith(\"_\"))\n .map(([key, value]) => [key, normalizeDynamicValue(value)]),\n );\n\nexport const denormalizeDynamicValue = (\n value: unknown,\n metadata?: OpcuaDynamicValueMetadata,\n): unknown => {\n if (Array.isArray(value)) {\n return value.map((item) => denormalizeDynamicValue(item, metadata));\n }\n if (!value || typeof value !== \"object\") {\n return value;\n }\n const tagged = value as { readonly _tag?: string };\n switch (tagged._tag) {\n case \"DateTime\":\n assertDynamicDataType(value, metadata, DataType.DateTime);\n return new Date((value as { readonly iso: string }).iso);\n case \"ByteString\":\n assertDynamicDataType(value, metadata, DataType.ByteString);\n return Buffer.from(\n (value as { readonly base64: string }).base64,\n \"base64\",\n );\n case \"Int64\":\n assertDynamicDataType(value, metadata, DataType.Int64);\n return (value as { readonly text: string }).text;\n case \"UInt64\":\n assertDynamicDataType(value, metadata, DataType.UInt64);\n return (value as { readonly text: string }).text;\n case \"NodeId\":\n assertDynamicDataType(value, metadata, DataType.NodeId);\n return coerceNodeId((value as { readonly text: string }).text);\n case \"LocalizedText\": {\n assertDynamicDataType(value, metadata, DataType.LocalizedText);\n const text = value as { readonly text: string; readonly locale?: string };\n return new LocalizedText({ text: text.text, locale: text.locale });\n }\n case \"QualifiedName\": {\n assertDynamicDataType(value, metadata, DataType.QualifiedName);\n const name = value as {\n readonly namespaceIndex: number;\n readonly name: string;\n };\n return new QualifiedName({\n namespaceIndex: name.namespaceIndex,\n name: name.name,\n });\n }\n case \"ExtensionObject\":\n throw new TypeError(\"ExtensionObject dynamic writes require a schema\");\n case \"Object\":\n throw new TypeError(\"Object dynamic writes require a schema\");\n default:\n if (\n metadata?.raw.dataType === DataType.ExtensionObject &&\n value !== null &&\n value !== undefined\n ) {\n throw new TypeError(\"ExtensionObject dynamic writes require a schema\");\n }\n return value;\n }\n};\n\nconst objectTypeName = (value: object): string | undefined => {\n const name = value.constructor?.name;\n return name && name !== \"Object\" ? name : undefined;\n};\n\nconst assertDynamicDataType = (\n value: unknown,\n metadata: OpcuaDynamicValueMetadata | undefined,\n expected: DataType,\n) => {\n if (metadata && metadata.raw.dataType !== expected) {\n throw new TypeError(\n `Cannot write ${(value as { readonly _tag?: string })._tag ?? \"value\"} to DataType.${DataType[metadata.raw.dataType]}`,\n );\n }\n};\n\nexport const normalizeTimestamp = (timestamp: Date | null | undefined) =>\n timestamp instanceof Date ? timestamp.toISOString() : undefined;\nexport const isGood = (statusCode: StatusCode) => statusCode.isGood();\nexport const isArrayRank = (valueRank: number) => valueRank >= 1;\n"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { StatusCode } from "node-opcua";
2
+ import { Effect } from "effect";
3
+
4
+ //#region src/internal/values/result.d.ts
5
+ type StatusDecodeResultInput<Value, Status, Output> = {
6
+ readonly statusCode: StatusCode;
7
+ readonly status: Status;
8
+ readonly decode: Effect.Effect<Value, unknown>;
9
+ readonly value: (decoded: Value) => Output;
10
+ readonly nonGoodStatus: (status: Status) => Output;
11
+ readonly decodeError: (error: unknown, status: Status) => Output;
12
+ };
13
+ declare const resultFromStatusAndDecode: <Value, Status, Output>(input: StatusDecodeResultInput<Value, Status, Output>) => Effect.Effect<Output>;
14
+ //#endregion
15
+ export { StatusDecodeResultInput, resultFromStatusAndDecode };
16
+ //# sourceMappingURL=result.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.d.mts","names":[],"sources":["../../../src/internal/values/result.ts"],"sourcesContent":[],"mappings":";;;;KAKY;uBACW;EADX,SAAA,MAAA,EAEO,MAFP;EACW,SAAA,MAAA,EAEJ,MAAA,CAAO,MAFH,CAEU,KAFV,EAAA,OAAA,CAAA;EACJ,SAAA,KAAA,EAAA,CAAA,OAAA,EAES,KAFT,EAAA,GAEmB,MAFnB;EACc,SAAA,aAAA,EAAA,CAAA,MAAA,EAEE,MAFF,EAAA,GAEa,MAFb;EAAd,SAAO,WAAA,EAAA,CAAA,KAAA,EAAA,OAAA,EAAA,MAAA,EAGuB,MAHvB,EAAA,GAGkC,MAHlC;CACE;AAAU,cAKzB,yBALyB,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,MAAA,CAAA,CAAA,KAAA,EAM7B,uBAN6B,CAML,KANK,EAME,MANF,EAMU,MANV,CAAA,EAAA,GAOnC,MAAA,CAAO,MAP4B,CAOrB,MAPqB,CAAA"}
@@ -0,0 +1,15 @@
1
+ import { isGood } from "./normalize.mjs";
2
+ import { Effect } from "effect";
3
+
4
+ //#region src/internal/values/result.ts
5
+ const resultFromStatusAndDecode = (input) => {
6
+ if (!isGood(input.statusCode)) return Effect.succeed(input.nonGoodStatus(input.status));
7
+ return Effect.match(input.decode, {
8
+ onFailure: (error) => input.decodeError(error, input.status),
9
+ onSuccess: input.value
10
+ });
11
+ };
12
+
13
+ //#endregion
14
+ export { resultFromStatusAndDecode };
15
+ //# sourceMappingURL=result.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.mjs","names":[],"sources":["../../../src/internal/values/result.ts"],"sourcesContent":["import { Effect } from \"effect\";\nimport type { StatusCode } from \"node-opcua\";\n\nimport { isGood } from \"./normalize.js\";\n\nexport type StatusDecodeResultInput<Value, Status, Output> = {\n readonly statusCode: StatusCode;\n readonly status: Status;\n readonly decode: Effect.Effect<Value, unknown>;\n readonly value: (decoded: Value) => Output;\n readonly nonGoodStatus: (status: Status) => Output;\n readonly decodeError: (error: unknown, status: Status) => Output;\n};\n\nexport const resultFromStatusAndDecode = <Value, Status, Output>(\n input: StatusDecodeResultInput<Value, Status, Output>,\n): Effect.Effect<Output> => {\n if (!isGood(input.statusCode)) {\n return Effect.succeed(input.nonGoodStatus(input.status));\n }\n return Effect.match(input.decode, {\n onFailure: (error) => input.decodeError(error, input.status),\n onSuccess: input.value,\n });\n};\n"],"mappings":";;;;AAcA,MAAa,6BACX,UAC0B;AAC1B,KAAI,CAAC,OAAO,MAAM,WAAW,CAC3B,QAAO,OAAO,QAAQ,MAAM,cAAc,MAAM,OAAO,CAAC;AAE1D,QAAO,OAAO,MAAM,MAAM,QAAQ;EAChC,YAAY,UAAU,MAAM,YAAY,OAAO,MAAM,OAAO;EAC5D,WAAW,MAAM;EAClB,CAAC"}