@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,127 @@
1
+ import { Effect, PubSub } from "effect";
2
+
3
+ //#region src/internal/events/wire.ts
4
+ const EventBus = {
5
+ publishUnsafe: (pubsub, event) => PubSub.publishUnsafe(pubsub, event),
6
+ wireEmitter: (emitter, mappings, pubsub) => Effect.acquireRelease(Effect.sync(() => mappings.map((mapping) => {
7
+ const listener = (...args) => {
8
+ EventBus.publishUnsafe(pubsub, mapping.make(...args));
9
+ };
10
+ emitter.on(mapping.event, listener);
11
+ return {
12
+ event: mapping.event,
13
+ listener
14
+ };
15
+ })), (listeners) => Effect.sync(() => {
16
+ for (const { event, listener } of listeners) if (emitter.off) emitter.off(event, listener);
17
+ else emitter.removeListener?.(event, listener);
18
+ }))
19
+ };
20
+ const wireClientEvents = (client, events) => EventBus.wireEmitter(client, [
21
+ {
22
+ event: "backoff",
23
+ make: (...unsafeRaw) => ({
24
+ _tag: "Backoff",
25
+ unsafeRaw
26
+ })
27
+ },
28
+ {
29
+ event: "start_reconnection",
30
+ make: (...unsafeRaw) => ({
31
+ _tag: "StartReconnection",
32
+ unsafeRaw
33
+ })
34
+ },
35
+ {
36
+ event: "after_reconnection",
37
+ make: (...unsafeRaw) => ({
38
+ _tag: "AfterReconnection",
39
+ unsafeRaw
40
+ })
41
+ },
42
+ {
43
+ event: "connection_lost",
44
+ make: (...unsafeRaw) => ({
45
+ _tag: "ConnectionLost",
46
+ unsafeRaw
47
+ })
48
+ },
49
+ {
50
+ event: "connection_reestablished",
51
+ make: (...unsafeRaw) => ({
52
+ _tag: "ConnectionReestablished",
53
+ unsafeRaw
54
+ })
55
+ }
56
+ ], events);
57
+ const wireSessionEvents = (session, events) => EventBus.wireEmitter(session, [
58
+ {
59
+ event: "keepalive",
60
+ make: (unsafeRaw) => ({
61
+ _tag: "KeepAlive",
62
+ unsafeRaw
63
+ })
64
+ },
65
+ {
66
+ event: "keepalive_failure",
67
+ make: (unsafeRaw) => ({
68
+ _tag: "KeepAliveFailure",
69
+ unsafeRaw
70
+ })
71
+ },
72
+ {
73
+ event: "session_closed",
74
+ make: (unsafeRaw) => ({
75
+ _tag: "SessionClosed",
76
+ unsafeRaw
77
+ })
78
+ },
79
+ {
80
+ event: "session_restored",
81
+ make: () => ({ _tag: "SessionRestored" })
82
+ }
83
+ ], events);
84
+ const wireSubscriptionEvents = (subscription, events) => EventBus.wireEmitter(subscription, [
85
+ {
86
+ event: "started",
87
+ make: (subscriptionId) => ({
88
+ _tag: "Started",
89
+ subscriptionId: Number(subscriptionId)
90
+ })
91
+ },
92
+ {
93
+ event: "terminated",
94
+ make: (...unsafeRaw) => ({
95
+ _tag: "Terminated",
96
+ subscriptionId: subscription.subscriptionId,
97
+ cause: unsafeRaw
98
+ })
99
+ },
100
+ {
101
+ event: "keepalive",
102
+ make: () => ({
103
+ _tag: "KeepAlive",
104
+ subscriptionId: subscription.subscriptionId
105
+ })
106
+ },
107
+ {
108
+ event: "internal_error",
109
+ make: (cause) => ({
110
+ _tag: "InternalError",
111
+ subscriptionId: subscription.subscriptionId,
112
+ cause
113
+ })
114
+ },
115
+ {
116
+ event: "status_changed",
117
+ make: (...unsafeRaw) => ({
118
+ _tag: "StatusChanged",
119
+ subscriptionId: subscription.subscriptionId,
120
+ unsafeRaw
121
+ })
122
+ }
123
+ ], events);
124
+
125
+ //#endregion
126
+ export { EventBus, wireClientEvents, wireSessionEvents, wireSubscriptionEvents };
127
+ //# sourceMappingURL=wire.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire.mjs","names":[],"sources":["../../../src/internal/events/wire.ts"],"sourcesContent":["import type {\n ClientSession,\n ClientSubscription,\n OPCUAClient,\n} from \"node-opcua\";\nimport { Effect, PubSub } from \"effect\";\n\nimport type {\n OpcuaClientEvent,\n OpcuaSessionEvent,\n OpcuaSubscriptionEvent,\n} from \"./model.js\";\n\ntype Emitter = {\n readonly on: (\n event: string,\n listener: (...args: ReadonlyArray<unknown>) => void,\n ) => unknown;\n readonly off?: (\n event: string,\n listener: (...args: ReadonlyArray<unknown>) => void,\n ) => unknown;\n readonly removeListener?: (\n event: string,\n listener: (...args: ReadonlyArray<unknown>) => void,\n ) => unknown;\n};\n\ntype EventMapping<A> = {\n readonly event: string;\n readonly make: (...args: ReadonlyArray<unknown>) => A;\n};\n\nexport const EventBus = {\n publishUnsafe: <A>(pubsub: PubSub.PubSub<A>, event: A) =>\n PubSub.publishUnsafe(pubsub, event),\n wireEmitter: <A>(\n emitter: Emitter,\n mappings: ReadonlyArray<EventMapping<A>>,\n pubsub: PubSub.PubSub<A>,\n ) =>\n Effect.acquireRelease(\n Effect.sync(() =>\n mappings.map((mapping) => {\n const listener = (...args: ReadonlyArray<unknown>) => {\n EventBus.publishUnsafe(pubsub, mapping.make(...args));\n };\n emitter.on(mapping.event, listener);\n return { event: mapping.event, listener };\n }),\n ),\n (listeners) =>\n Effect.sync(() => {\n for (const { event, listener } of listeners) {\n if (emitter.off) emitter.off(event, listener);\n else emitter.removeListener?.(event, listener);\n }\n }),\n ),\n};\n\nexport const wireClientEvents = (\n client: OPCUAClient,\n events: PubSub.PubSub<OpcuaClientEvent>,\n) =>\n EventBus.wireEmitter(\n client as unknown as Emitter,\n [\n {\n event: \"backoff\",\n make: (...unsafeRaw) => ({ _tag: \"Backoff\", unsafeRaw }) as const,\n },\n {\n event: \"start_reconnection\",\n make: (...unsafeRaw) =>\n ({ _tag: \"StartReconnection\", unsafeRaw }) as const,\n },\n {\n event: \"after_reconnection\",\n make: (...unsafeRaw) =>\n ({ _tag: \"AfterReconnection\", unsafeRaw }) as const,\n },\n {\n event: \"connection_lost\",\n make: (...unsafeRaw) =>\n ({ _tag: \"ConnectionLost\", unsafeRaw }) as const,\n },\n {\n event: \"connection_reestablished\",\n make: (...unsafeRaw) =>\n ({ _tag: \"ConnectionReestablished\", unsafeRaw }) as const,\n },\n ],\n events,\n );\n\nexport const wireSessionEvents = (\n session: ClientSession,\n events: PubSub.PubSub<OpcuaSessionEvent>,\n) =>\n EventBus.wireEmitter(\n session as unknown as Emitter,\n [\n {\n event: \"keepalive\",\n make: (unsafeRaw) => ({ _tag: \"KeepAlive\", unsafeRaw }) as const,\n },\n {\n event: \"keepalive_failure\",\n make: (unsafeRaw) => ({ _tag: \"KeepAliveFailure\", unsafeRaw }) as const,\n },\n {\n event: \"session_closed\",\n make: (unsafeRaw) => ({ _tag: \"SessionClosed\", unsafeRaw }) as const,\n },\n {\n event: \"session_restored\",\n make: () => ({ _tag: \"SessionRestored\" }) as const,\n },\n ],\n events,\n );\n\nexport const wireSubscriptionEvents = (\n subscription: ClientSubscription,\n events: PubSub.PubSub<OpcuaSubscriptionEvent>,\n) =>\n EventBus.wireEmitter(\n subscription as unknown as Emitter,\n [\n {\n event: \"started\",\n make: (subscriptionId) =>\n ({\n _tag: \"Started\",\n subscriptionId: Number(subscriptionId),\n }) as const,\n },\n {\n event: \"terminated\",\n make: (...unsafeRaw) =>\n ({\n _tag: \"Terminated\",\n subscriptionId: subscription.subscriptionId,\n cause: unsafeRaw,\n }) as const,\n },\n {\n event: \"keepalive\",\n make: () =>\n ({\n _tag: \"KeepAlive\",\n subscriptionId: subscription.subscriptionId,\n }) as const,\n },\n {\n event: \"internal_error\",\n make: (cause) =>\n ({\n _tag: \"InternalError\",\n subscriptionId: subscription.subscriptionId,\n cause,\n }) as const,\n },\n {\n event: \"status_changed\",\n make: (...unsafeRaw) =>\n ({\n _tag: \"StatusChanged\",\n subscriptionId: subscription.subscriptionId,\n unsafeRaw,\n }) as const,\n },\n ],\n events,\n );\n"],"mappings":";;;AAiCA,MAAa,WAAW;CACtB,gBAAmB,QAA0B,UAC3C,OAAO,cAAc,QAAQ,MAAM;CACrC,cACE,SACA,UACA,WAEA,OAAO,eACL,OAAO,WACL,SAAS,KAAK,YAAY;EACxB,MAAM,YAAY,GAAG,SAAiC;AACpD,YAAS,cAAc,QAAQ,QAAQ,KAAK,GAAG,KAAK,CAAC;;AAEvD,UAAQ,GAAG,QAAQ,OAAO,SAAS;AACnC,SAAO;GAAE,OAAO,QAAQ;GAAO;GAAU;GACzC,CACH,GACA,cACC,OAAO,WAAW;AAChB,OAAK,MAAM,EAAE,OAAO,cAAc,UAChC,KAAI,QAAQ,IAAK,SAAQ,IAAI,OAAO,SAAS;MACxC,SAAQ,iBAAiB,OAAO,SAAS;GAEhD,CACL;CACJ;AAED,MAAa,oBACX,QACA,WAEA,SAAS,YACP,QACA;CACE;EACE,OAAO;EACP,OAAO,GAAG,eAAe;GAAE,MAAM;GAAW;GAAW;EACxD;CACD;EACE,OAAO;EACP,OAAO,GAAG,eACP;GAAE,MAAM;GAAqB;GAAW;EAC5C;CACD;EACE,OAAO;EACP,OAAO,GAAG,eACP;GAAE,MAAM;GAAqB;GAAW;EAC5C;CACD;EACE,OAAO;EACP,OAAO,GAAG,eACP;GAAE,MAAM;GAAkB;GAAW;EACzC;CACD;EACE,OAAO;EACP,OAAO,GAAG,eACP;GAAE,MAAM;GAA2B;GAAW;EAClD;CACF,EACD,OACD;AAEH,MAAa,qBACX,SACA,WAEA,SAAS,YACP,SACA;CACE;EACE,OAAO;EACP,OAAO,eAAe;GAAE,MAAM;GAAa;GAAW;EACvD;CACD;EACE,OAAO;EACP,OAAO,eAAe;GAAE,MAAM;GAAoB;GAAW;EAC9D;CACD;EACE,OAAO;EACP,OAAO,eAAe;GAAE,MAAM;GAAiB;GAAW;EAC3D;CACD;EACE,OAAO;EACP,aAAa,EAAE,MAAM,mBAAmB;EACzC;CACF,EACD,OACD;AAEH,MAAa,0BACX,cACA,WAEA,SAAS,YACP,cACA;CACE;EACE,OAAO;EACP,OAAO,oBACJ;GACC,MAAM;GACN,gBAAgB,OAAO,eAAe;GACvC;EACJ;CACD;EACE,OAAO;EACP,OAAO,GAAG,eACP;GACC,MAAM;GACN,gBAAgB,aAAa;GAC7B,OAAO;GACR;EACJ;CACD;EACE,OAAO;EACP,aACG;GACC,MAAM;GACN,gBAAgB,aAAa;GAC9B;EACJ;CACD;EACE,OAAO;EACP,OAAO,WACJ;GACC,MAAM;GACN,gBAAgB,aAAa;GAC7B;GACD;EACJ;CACD;EACE,OAAO;EACP,OAAO,GAAG,eACP;GACC,MAAM;GACN,gBAAgB,aAAa;GAC7B;GACD;EACJ;CACF,EACD,OACD"}
@@ -0,0 +1,2 @@
1
+ import { methodArgumentMetadataFromRaw, readBooleanAttribute, resolveMethodMapping } from "../method/arguments.mjs";
2
+ export { methodArgumentMetadataFromRaw, readBooleanAttribute, resolveMethodMapping };
@@ -0,0 +1,3 @@
1
+ import { methodArgumentMetadataFromRaw, readBooleanAttribute, resolveMethodMapping } from "../method/arguments.mjs";
2
+
3
+ export { methodArgumentMetadataFromRaw, readBooleanAttribute, resolveMethodMapping };
@@ -0,0 +1,2 @@
1
+ import { MetadataService, makeMetadataService } from "./service.mjs";
2
+ export { type MetadataService, makeMetadataService };
@@ -0,0 +1,3 @@
1
+ import { makeMetadataService } from "./service.mjs";
2
+
3
+ export { makeMetadataService };
@@ -0,0 +1,23 @@
1
+ import { AnyVariableDef, NodeIdString, VariableMetadata } from "../../OpcuaVariable.mjs";
2
+ import "../common/node-id.mjs";
3
+ import { OpcuaStructureRuntime } from "../structures/runtime.mjs";
4
+ import { OpcuaAccessDeniedError, OpcuaConfigurationError, OpcuaMethodNotExecutableError, OpcuaServiceError } from "../../OpcuaError.mjs";
5
+ import { AnyMethodDef, MethodMetadata } from "../../OpcuaMethod.mjs";
6
+ import { OpcuaAccessBits, OpcuaMetadataAttribute, OpcuaMetadataReadFailure, OpcuaNodeMetadata, OpcuaNodeMetadataResult } from "../../OpcuaSession.mjs";
7
+ import { ClientSession, DataType, NodeId } from "node-opcua";
8
+ import { Effect } from "effect";
9
+
10
+ //#region src/internal/metadata/service.d.ts
11
+ type MetadataService = {
12
+ readonly namespaceArray: () => Effect.Effect<readonly string[], OpcuaServiceError | OpcuaConfigurationError>;
13
+ readonly node: (nodeId: NodeIdString) => Effect.Effect<OpcuaNodeMetadata, OpcuaServiceError | OpcuaConfigurationError>;
14
+ readonly nodes: (nodeIds: readonly NodeIdString[]) => Effect.Effect<readonly OpcuaNodeMetadataResult[], OpcuaServiceError | OpcuaConfigurationError>;
15
+ readonly variable: (def: AnyVariableDef) => Effect.Effect<VariableMetadata, OpcuaServiceError | OpcuaConfigurationError | OpcuaAccessDeniedError>;
16
+ readonly method: (def: AnyMethodDef) => Effect.Effect<MethodMetadata, OpcuaServiceError | OpcuaConfigurationError | OpcuaMethodNotExecutableError>;
17
+ readonly builtInDataType: (dataTypeNodeId: NodeId) => Effect.Effect<DataType, OpcuaServiceError | OpcuaConfigurationError>;
18
+ readonly invalidate: Effect.Effect<void>;
19
+ };
20
+ declare const makeMetadataService: (session: ClientSession, structureRuntime: OpcuaStructureRuntime) => MetadataService;
21
+ //#endregion
22
+ export { MetadataService, type OpcuaAccessBits, type OpcuaMetadataAttribute, type OpcuaMetadataReadFailure, type OpcuaNodeMetadata, type OpcuaNodeMetadataResult, makeMetadataService };
23
+ //# sourceMappingURL=service.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.mts","names":[],"sources":["../../../src/internal/metadata/service.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;KAsEY,eAAA;EAAA,SAAA,cAAe,EAAA,GAAA,GACM,MAAA,CAAO,MADb,CAAA,SAAA,MAAA,EAAA,EAGvB,iBAHuB,GAGH,uBAHG,CAAA;EAGvB,SAAA,IAAA,EAAA,CAAA,MAAA,EAGQ,YAHR,EAAA,GAIG,MAAA,CAAO,MAJV,CAKA,iBALA,EAMA,iBANA,GAMoB,uBANpB,CAAA;EAAoB,SAAA,KAAA,EAAA,CAAA,OAAA,EAAA,SASF,YATE,EAAA,EAAA,GAUjB,MAAA,CAAO,MAVU,CAAA,SAWX,uBAXW,EAAA,EAYpB,iBAZoB,GAYA,uBAZA,CAAA;EAFS,SAAO,QAAA,EAAA,CAAA,GAAA,EAiB/B,cAjB+B,EAAA,GAkBjC,MAAA,CAAO,MAlB0B,CAmBpC,gBAnBoC,EAoBpC,iBApBoC,GAoBhB,uBApBgB,GAoBU,sBApBV,CAAA;EAK5B,SAAA,MAAA,EAAA,CAAA,GAAA,EAkBH,YAlBG,EAAA,GAmBL,MAAA,CAAO,MAnBF,CAoBR,cApBQ,EAqBR,iBArBQ,GAqBY,uBArBZ,GAqBsC,6BArBtC,CAAA;EAER,SAAA,eAAA,EAAA,CAAA,cAAA,EAsBgB,MAtBhB,EAAA,GAuBG,MAAA,CAAO,MAvBV,CAuBiB,QAvBjB,EAuB2B,iBAvB3B,GAuB+C,uBAvB/C,CAAA;EACA,SAAA,UAAA,EAuBmB,MAAA,CAAO,MAvB1B,CAAA,IAAA,CAAA;CAAoB;AAFjB,cAqCM,mBArCC,EAAA,CAAA,OAAA,EAsCH,aAtCG,EAAA,gBAAA,EAuCM,qBAvCN,EAAA,GAwCX,eAxCW"}
@@ -0,0 +1,416 @@
1
+ import { isGood, normalizeLocalizedText, normalizeQualifiedName, normalizeStatusCode } from "../values/normalize.mjs";
2
+ import { configurationError, isConfigurationError, methodNotExecutableError, serviceError } from "../../OpcuaError.mjs";
3
+ import { Codec } from "../values/codec.mjs";
4
+ import { accessDeniedError, codecMetadata, variableAccessCapabilities, variableMetadataFromRaw } from "../variable/operations.mjs";
5
+ import { methodArgumentMetadataFromRaw, readBooleanAttribute, resolveMethodMapping } from "../method/arguments.mjs";
6
+ import { AccessLevelFlag, AttributeIds, BrowseDirection, DataType, DataTypeIds, NodeClass, NodeId, NodeIdType, ReferenceTypeIds, StatusCodes, coerceNodeId } from "node-opcua";
7
+ import { Effect } from "effect";
8
+
9
+ //#region src/internal/metadata/service.ts
10
+ const makeMetadataService = (session, structureRuntime) => {
11
+ let namespaceArrayCache;
12
+ const variableCache = /* @__PURE__ */ new Map();
13
+ const methodCache = /* @__PURE__ */ new Map();
14
+ const builtInDataTypeCache = /* @__PURE__ */ new Map();
15
+ const namespaceArray = () => Effect.suspend(() => {
16
+ if (namespaceArrayCache !== void 0) return Effect.succeed(namespaceArrayCache);
17
+ return readNamespaceArray(session).pipe(Effect.tap((value) => Effect.sync(() => {
18
+ namespaceArrayCache = value;
19
+ })));
20
+ });
21
+ const nodes = (nodeIds) => readManyNodeMetadata(session, namespaceArray, nodeIds);
22
+ const node = (nodeId) => Effect.gen(function* () {
23
+ const [result] = yield* nodes([nodeId]);
24
+ if (!result || result._tag === "Failure") return yield* Effect.fail(configurationError({
25
+ operation: "metadata.node",
26
+ nodeId,
27
+ cause: result?._tag === "Failure" ? result.reason : "No metadata result was returned"
28
+ }));
29
+ return result.metadata;
30
+ });
31
+ const builtInDataType = (dataTypeNodeId) => Effect.suspend(() => {
32
+ const key = dataTypeNodeId.toString();
33
+ const cached = builtInDataTypeCache.get(key);
34
+ if (cached !== void 0) return Effect.succeed(cached);
35
+ return resolveBuiltInDataType(session, dataTypeNodeId).pipe(Effect.tap((value) => Effect.sync(() => {
36
+ builtInDataTypeCache.set(key, value);
37
+ })));
38
+ });
39
+ const rawVariableMetadata = (nodeId) => Effect.suspend(() => {
40
+ const cached = variableCache.get(nodeId);
41
+ if (cached) return Effect.succeed(cached);
42
+ return discoverVariableMetadata(session, nodeId, builtInDataType).pipe(Effect.tap((metadata) => Effect.sync(() => {
43
+ variableCache.set(nodeId, metadata);
44
+ })));
45
+ });
46
+ const variable = (def) => Effect.gen(function* () {
47
+ const metadata = yield* rawVariableMetadata(def.nodeId);
48
+ for (const capability of variableAccessCapabilities(def.access)) {
49
+ const error = accessDeniedError(def.nodeId, capability, metadata.accessLevel, metadata.userAccessLevel);
50
+ if (error) return yield* Effect.fail(error);
51
+ }
52
+ if (Codec.requiresStructureRuntime(def.codec)) yield* structureRuntime.ensureInitialized();
53
+ yield* Codec.validateMetadata(def.codec, codecMetadata(metadata));
54
+ return metadata;
55
+ });
56
+ const rawMethodMetadata = (def) => Effect.suspend(() => {
57
+ const key = `${def.objectId}\u0000${def.methodId}`;
58
+ const cached = methodCache.get(key);
59
+ if (cached) return Effect.succeed(cached);
60
+ return discoverMethodBaseMetadata(session, def, builtInDataType).pipe(Effect.tap((metadata) => Effect.sync(() => {
61
+ methodCache.set(key, metadata);
62
+ })));
63
+ });
64
+ const method = (def) => Effect.gen(function* () {
65
+ const base = yield* rawMethodMetadata(def);
66
+ if (!base.executable || base.userExecutable === false) return yield* Effect.fail(methodNotExecutableError({
67
+ objectId: def.objectId,
68
+ methodId: def.methodId,
69
+ executable: base.executable,
70
+ userExecutable: base.userExecutable
71
+ }));
72
+ if (Object.values(def.input ?? {}).some((arg) => Codec.requiresStructureRuntime(arg.codec)) || Object.values(def.output ?? {}).some((arg) => Codec.requiresStructureRuntime(arg.codec))) yield* structureRuntime.ensureInitialized();
73
+ const inputMapping = yield* resolveMethodMapping("method.input", def.methodId, base.inputArguments, def.input);
74
+ const outputMapping = yield* resolveMethodMapping("method.output", def.methodId, base.outputArguments, def.output);
75
+ return {
76
+ ...base,
77
+ inputMapping,
78
+ outputMapping
79
+ };
80
+ });
81
+ return {
82
+ namespaceArray,
83
+ node,
84
+ nodes,
85
+ variable,
86
+ method,
87
+ builtInDataType,
88
+ invalidate: Effect.sync(() => {
89
+ namespaceArrayCache = void 0;
90
+ variableCache.clear();
91
+ methodCache.clear();
92
+ builtInDataTypeCache.clear();
93
+ })
94
+ };
95
+ };
96
+ const readNamespaceArray = (session) => Effect.gen(function* () {
97
+ const dataValue = yield* Effect.tryPromise({
98
+ try: () => session.read({
99
+ nodeId: coerceNodeId("i=2255"),
100
+ attributeId: AttributeIds.Value
101
+ }, 0),
102
+ catch: (cause) => serviceError({
103
+ operation: "metadata.namespaceArray",
104
+ nodeId: "i=2255",
105
+ cause
106
+ })
107
+ });
108
+ if (!isGood(dataValue.statusCode)) return yield* Effect.fail(configurationError({
109
+ operation: "metadata.namespaceArray",
110
+ nodeId: "i=2255",
111
+ cause: normalizeStatusCode(dataValue.statusCode)
112
+ }));
113
+ const value = dataValue.value?.value;
114
+ if (!Array.isArray(value) || !value.every((item) => typeof item === "string")) return yield* Effect.fail(configurationError({
115
+ operation: "metadata.namespaceArray",
116
+ nodeId: "i=2255",
117
+ cause: "NamespaceArray value is not a string array"
118
+ }));
119
+ return [...value];
120
+ });
121
+ const metadataAttributes = [
122
+ ["NodeClass", AttributeIds.NodeClass],
123
+ ["BrowseName", AttributeIds.BrowseName],
124
+ ["DisplayName", AttributeIds.DisplayName],
125
+ ["Description", AttributeIds.Description],
126
+ ["DataType", AttributeIds.DataType],
127
+ ["ValueRank", AttributeIds.ValueRank],
128
+ ["ArrayDimensions", AttributeIds.ArrayDimensions],
129
+ ["AccessLevel", AttributeIds.AccessLevel],
130
+ ["UserAccessLevel", AttributeIds.UserAccessLevel]
131
+ ];
132
+ const maxMetadataNodesPerRead = 50;
133
+ const requiredMetadataAttributes = new Set(["NodeClass", "BrowseName"]);
134
+ const readManyNodeMetadata = (session, namespaceArray, nodeIds) => Effect.gen(function* () {
135
+ if (nodeIds.length === 0) return [];
136
+ const namespaceUris = yield* namespaceArray();
137
+ const results = [];
138
+ for (const batch of chunks(nodeIds, maxMetadataNodesPerRead)) {
139
+ const batchResults = yield* readNodeMetadataBatch(session, namespaceUris, batch);
140
+ results.push(...batchResults);
141
+ }
142
+ return results;
143
+ });
144
+ const readNodeMetadataBatch = (session, namespaceUris, nodeIds) => Effect.gen(function* () {
145
+ const readPlan = nodeIds.map((nodeId) => {
146
+ const parsed = coerceNodeId(nodeId);
147
+ return {
148
+ nodeId,
149
+ parsed,
150
+ nodesToRead: metadataAttributes.map(([attribute, attributeId]) => ({
151
+ nodeId: parsed,
152
+ attributeId,
153
+ attribute
154
+ }))
155
+ };
156
+ });
157
+ const flatNodes = readPlan.flatMap((entry) => entry.nodesToRead);
158
+ const values = yield* Effect.tryPromise({
159
+ try: () => session.read(flatNodes, 0),
160
+ catch: (cause) => serviceError({
161
+ operation: "metadata.nodes",
162
+ cause
163
+ })
164
+ });
165
+ if (values.length !== flatNodes.length) return yield* Effect.fail(serviceError({
166
+ operation: "metadata.nodes",
167
+ cause: `Expected ${flatNodes.length} DataValues, got ${values.length}`
168
+ }));
169
+ let offset = 0;
170
+ return readPlan.map((entry) => {
171
+ const valuesByAttribute = /* @__PURE__ */ new Map();
172
+ for (const [attribute] of metadataAttributes) valuesByAttribute.set(attribute, values[offset++]);
173
+ const failure = metadataFailure(valuesByAttribute);
174
+ if (failure) return {
175
+ _tag: "Failure",
176
+ nodeId: entry.nodeId,
177
+ reason: failure
178
+ };
179
+ return {
180
+ _tag: "Success",
181
+ nodeId: entry.nodeId,
182
+ metadata: nodeMetadataFromValues(entry.nodeId, entry.parsed.namespace, namespaceUris[entry.parsed.namespace], valuesByAttribute)
183
+ };
184
+ });
185
+ });
186
+ const chunks = (items, size) => {
187
+ const result = [];
188
+ for (let index = 0; index < items.length; index += size) result.push([...items.slice(index, index + size)]);
189
+ return result;
190
+ };
191
+ const metadataFailure = (values) => {
192
+ for (const attribute of requiredMetadataAttributes) {
193
+ const value = values.get(attribute);
194
+ if (!value || !isGood(value.statusCode)) return {
195
+ _tag: "NonGoodStatus",
196
+ attribute,
197
+ status: normalizeStatusCode(value?.statusCode ?? StatusCodes.BadInternalError)
198
+ };
199
+ }
200
+ if (typeof values.get("NodeClass")?.value?.value !== "number") return {
201
+ _tag: "InvalidValue",
202
+ attribute: "NodeClass",
203
+ message: "NodeClass value is not numeric"
204
+ };
205
+ if (!values.get("BrowseName")?.value?.value) return {
206
+ _tag: "InvalidValue",
207
+ attribute: "BrowseName",
208
+ message: "BrowseName value is missing"
209
+ };
210
+ };
211
+ const nodeMetadataFromValues = (nodeId, namespaceIndex, namespaceUri, values) => {
212
+ const browseNameValue = values.get("BrowseName")?.value?.value;
213
+ const displayNameValue = values.get("DisplayName");
214
+ const descriptionValue = values.get("Description");
215
+ const nodeClassNumber = values.get("NodeClass")?.value?.value;
216
+ const browseName = normalizeQualifiedName(browseNameValue);
217
+ return {
218
+ nodeId,
219
+ nodeClass: NodeClass[nodeClassNumber] ?? String(nodeClassNumber),
220
+ browseName: browseName.name,
221
+ browseNameNamespaceIndex: browseName.namespaceIndex,
222
+ displayName: localizedText(displayNameValue),
223
+ description: localizedText(descriptionValue),
224
+ dataType: nodeIdValue(values.get("DataType")),
225
+ valueRank: numberValue(values.get("ValueRank")),
226
+ arrayDimensions: numberArrayValue(values.get("ArrayDimensions")),
227
+ accessLevel: accessBits(values.get("AccessLevel")),
228
+ userAccessLevel: accessBits(values.get("UserAccessLevel")),
229
+ namespaceIndex,
230
+ namespaceUri
231
+ };
232
+ };
233
+ const localizedText = (dataValue) => {
234
+ if (!dataValue || !isGood(dataValue.statusCode) || !dataValue.value?.value) return;
235
+ return normalizeLocalizedText(dataValue.value.value).text;
236
+ };
237
+ const nodeIdValue = (dataValue) => {
238
+ if (!dataValue || !isGood(dataValue.statusCode)) return void 0;
239
+ const value = dataValue.value?.value;
240
+ return value instanceof NodeId ? value.toString() : void 0;
241
+ };
242
+ const numberValue = (dataValue) => {
243
+ if (!dataValue || !isGood(dataValue.statusCode)) return void 0;
244
+ const value = dataValue.value?.value;
245
+ return typeof value === "number" ? value : void 0;
246
+ };
247
+ const numberArrayValue = (dataValue) => {
248
+ if (!dataValue || !isGood(dataValue.statusCode)) return void 0;
249
+ const value = dataValue.value?.value;
250
+ if (!Array.isArray(value) || !value.every((item) => typeof item === "number")) return;
251
+ return [...value];
252
+ };
253
+ const accessBits = (dataValue) => {
254
+ const value = numberValue(dataValue);
255
+ if (value === void 0) return void 0;
256
+ return {
257
+ readable: (value & AccessLevelFlag.CurrentRead) !== 0,
258
+ writable: (value & AccessLevelFlag.CurrentWrite) !== 0
259
+ };
260
+ };
261
+ const discoverVariableMetadata = (session, nodeId, builtInDataType) => Effect.gen(function* () {
262
+ const nodes = [
263
+ AttributeIds.DataType,
264
+ AttributeIds.ValueRank,
265
+ AttributeIds.ArrayDimensions,
266
+ AttributeIds.AccessLevel,
267
+ AttributeIds.UserAccessLevel
268
+ ].map((attributeId) => ({
269
+ nodeId: coerceNodeId(nodeId),
270
+ attributeId
271
+ }));
272
+ const [dataTypeValue, valueRankValue, arrayDimensionsValue, accessLevelValue, userAccessLevelValue] = yield* Effect.tryPromise({
273
+ try: () => session.read(nodes, 0),
274
+ catch: (cause) => serviceError({
275
+ operation: "metadata.variable",
276
+ nodeId,
277
+ cause
278
+ })
279
+ });
280
+ if (!dataTypeValue || !isGood(dataTypeValue.statusCode) || !(dataTypeValue.value?.value instanceof NodeId)) return yield* Effect.fail(configurationError({
281
+ operation: "metadata.variable",
282
+ nodeId,
283
+ cause: "DataType is unreadable"
284
+ }));
285
+ if (!valueRankValue || !isGood(valueRankValue.statusCode) || typeof valueRankValue.value?.value !== "number") return yield* Effect.fail(configurationError({
286
+ operation: "metadata.variable",
287
+ nodeId,
288
+ cause: "ValueRank is unreadable"
289
+ }));
290
+ if (!accessLevelValue || !isGood(accessLevelValue.statusCode) || typeof accessLevelValue.value?.value !== "number") return yield* Effect.fail(configurationError({
291
+ operation: "metadata.variable",
292
+ nodeId,
293
+ cause: "AccessLevel is unreadable"
294
+ }));
295
+ const dataTypeNodeId = dataTypeValue.value.value;
296
+ const builtIn = yield* builtInDataType(dataTypeNodeId);
297
+ const userAccessLevel = userAccessLevelValue && isGood(userAccessLevelValue.statusCode) && typeof userAccessLevelValue.value?.value === "number" ? userAccessLevelValue.value.value : void 0;
298
+ return variableMetadataFromRaw({
299
+ nodeId,
300
+ dataTypeNodeId,
301
+ builtInDataType: builtIn,
302
+ valueRank: valueRankValue.value.value,
303
+ arrayDimensions: arrayDimensionsValue && isGood(arrayDimensionsValue.statusCode) && Array.isArray(arrayDimensionsValue.value?.value) ? arrayDimensionsValue.value.value : void 0,
304
+ accessLevel: accessLevelValue.value.value,
305
+ userAccessLevel
306
+ });
307
+ });
308
+ const discoverMethodBaseMetadata = (session, def, builtInDataType) => Effect.gen(function* () {
309
+ const methodId = yield* coerceNodeIdOrFail("metadata.method.methodId", def.methodId);
310
+ const argumentDefinition = yield* Effect.tryPromise({
311
+ try: () => session.getArgumentDefinition(methodId),
312
+ catch: (cause) => serviceError({
313
+ operation: "metadata.method.getArgumentDefinition",
314
+ nodeId: def.methodId,
315
+ cause
316
+ })
317
+ });
318
+ const [executable, userExecutable] = yield* readExecutableAttributes(session, def, methodId);
319
+ const inputArguments = yield* normalizeArguments(def.methodId, argumentDefinition.inputArguments ?? [], builtInDataType);
320
+ const outputArguments = yield* normalizeArguments(def.methodId, argumentDefinition.outputArguments ?? [], builtInDataType);
321
+ return {
322
+ objectId: def.objectId,
323
+ methodId: def.methodId,
324
+ executable,
325
+ userExecutable,
326
+ inputArguments,
327
+ outputArguments
328
+ };
329
+ });
330
+ const readExecutableAttributes = (session, def, methodId) => Effect.gen(function* () {
331
+ const [executableValue, userExecutableValue] = yield* Effect.tryPromise({
332
+ try: () => session.read([{
333
+ nodeId: methodId,
334
+ attributeId: AttributeIds.Executable
335
+ }, {
336
+ nodeId: methodId,
337
+ attributeId: AttributeIds.UserExecutable
338
+ }], 0),
339
+ catch: (cause) => serviceError({
340
+ operation: "metadata.method.executable",
341
+ nodeId: def.methodId,
342
+ cause
343
+ })
344
+ });
345
+ const executable = readBooleanAttribute(executableValue, "metadata.method.executable", def.methodId, true);
346
+ const userExecutable = readBooleanAttribute(userExecutableValue, "metadata.method.userExecutable", def.methodId, false);
347
+ if (isConfigurationError(executable)) return yield* Effect.fail(executable);
348
+ if (isConfigurationError(userExecutable)) return yield* Effect.fail(userExecutable);
349
+ return [executable, userExecutable];
350
+ });
351
+ const normalizeArguments = (methodNodeId, arguments_, builtInDataType) => Effect.forEach(arguments_, (argument) => Effect.gen(function* () {
352
+ const dataTypeNodeId = argument.dataType instanceof NodeId ? argument.dataType : yield* coerceNodeIdOrFail("metadata.method.argument.dataType", String(argument.dataType));
353
+ return methodArgumentMetadataFromRaw(argument, dataTypeNodeId, yield* builtInDataType(dataTypeNodeId));
354
+ })).pipe(Effect.mapError((error) => isConfigurationError(error) ? configurationError({
355
+ operation: "metadata.method.argument",
356
+ nodeId: methodNodeId,
357
+ cause: error.reason.cause
358
+ }) : error));
359
+ const resolveBuiltInDataType = (session, dataTypeNodeId) => Effect.gen(function* () {
360
+ let current = dataTypeNodeId;
361
+ const visited = /* @__PURE__ */ new Set();
362
+ while (true) {
363
+ const builtIn = builtInDataTypeFromNodeId(current);
364
+ if (builtIn !== void 0) return builtIn;
365
+ const key = current.toString();
366
+ if (visited.has(key)) return yield* Effect.fail(configurationError({
367
+ operation: "metadata.builtInDataType",
368
+ nodeId: dataTypeNodeId.toString(),
369
+ cause: `DataType hierarchy contains a cycle at ${key}`
370
+ }));
371
+ visited.add(key);
372
+ const superType = yield* browseDataTypeSuperType(session, current);
373
+ if (!superType) return yield* Effect.fail(configurationError({
374
+ operation: "metadata.builtInDataType",
375
+ nodeId: dataTypeNodeId.toString(),
376
+ cause: `Could not resolve built-in DataType for ${dataTypeNodeId.toString()}`
377
+ }));
378
+ current = superType;
379
+ }
380
+ });
381
+ const builtInDataTypeFromNodeId = (nodeId) => {
382
+ if (nodeId.identifierType === NodeIdType.NUMERIC && nodeId.namespace === 0 && nodeId.value === DataTypeIds.Enumeration) return DataType.Int32;
383
+ if (nodeId.identifierType === NodeIdType.NUMERIC && nodeId.namespace === 0 && typeof nodeId.value === "number" && nodeId.value <= DataType.DiagnosticInfo && DataType[nodeId.value] !== void 0) return nodeId.value;
384
+ };
385
+ const browseDataTypeSuperType = (session, dataTypeNodeId) => Effect.tryPromise({
386
+ try: async () => {
387
+ const browse = {
388
+ browseDirection: BrowseDirection.Inverse,
389
+ includeSubtypes: false,
390
+ nodeId: dataTypeNodeId,
391
+ referenceTypeId: coerceNodeId(ReferenceTypeIds.HasSubtype),
392
+ resultMask: 1
393
+ };
394
+ const result = await session.browse(browse);
395
+ if (!isGood(result.statusCode)) throw new Error(result.statusCode.toString());
396
+ const nodeId = result.references?.[0]?.nodeId;
397
+ return nodeId ? coerceNodeId(nodeId) : void 0;
398
+ },
399
+ catch: (cause) => serviceError({
400
+ operation: "metadata.browseDataTypeSuperType",
401
+ nodeId: dataTypeNodeId.toString(),
402
+ cause
403
+ })
404
+ });
405
+ const coerceNodeIdOrFail = (operation, nodeId) => Effect.try({
406
+ try: () => coerceNodeId(nodeId),
407
+ catch: (cause) => configurationError({
408
+ operation,
409
+ nodeId: String(nodeId),
410
+ cause
411
+ })
412
+ });
413
+
414
+ //#endregion
415
+ export { makeMetadataService };
416
+ //# sourceMappingURL=service.mjs.map