effect 4.0.0-beta.17 → 4.0.0-beta.19

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 (164) hide show
  1. package/dist/Array.d.ts +127 -299
  2. package/dist/Array.d.ts.map +1 -1
  3. package/dist/Array.js +102 -62
  4. package/dist/Array.js.map +1 -1
  5. package/dist/Cache.d.ts.map +1 -1
  6. package/dist/Cache.js +5 -4
  7. package/dist/Cache.js.map +1 -1
  8. package/dist/Channel.d.ts +97 -11
  9. package/dist/Channel.d.ts.map +1 -1
  10. package/dist/Channel.js +72 -29
  11. package/dist/Channel.js.map +1 -1
  12. package/dist/Chunk.d.ts +54 -247
  13. package/dist/Chunk.d.ts.map +1 -1
  14. package/dist/Chunk.js +36 -67
  15. package/dist/Chunk.js.map +1 -1
  16. package/dist/Effect.d.ts +337 -437
  17. package/dist/Effect.d.ts.map +1 -1
  18. package/dist/Effect.js +118 -134
  19. package/dist/Effect.js.map +1 -1
  20. package/dist/Filter.d.ts +0 -33
  21. package/dist/Filter.d.ts.map +1 -1
  22. package/dist/Filter.js +0 -13
  23. package/dist/Filter.js.map +1 -1
  24. package/dist/HashMap.d.ts +15 -14
  25. package/dist/HashMap.d.ts.map +1 -1
  26. package/dist/HashMap.js +4 -4
  27. package/dist/HashMap.js.map +1 -1
  28. package/dist/Iterable.d.ts +40 -39
  29. package/dist/Iterable.d.ts.map +1 -1
  30. package/dist/Iterable.js +94 -22
  31. package/dist/Iterable.js.map +1 -1
  32. package/dist/Option.d.ts +22 -15
  33. package/dist/Option.d.ts.map +1 -1
  34. package/dist/Option.js +14 -7
  35. package/dist/Option.js.map +1 -1
  36. package/dist/Pull.d.ts.map +1 -1
  37. package/dist/Pull.js +1 -1
  38. package/dist/Pull.js.map +1 -1
  39. package/dist/Record.d.ts +24 -120
  40. package/dist/Record.d.ts.map +1 -1
  41. package/dist/Record.js +21 -41
  42. package/dist/Record.js.map +1 -1
  43. package/dist/Sink.d.ts +11 -11
  44. package/dist/Sink.d.ts.map +1 -1
  45. package/dist/Sink.js +53 -6
  46. package/dist/Sink.js.map +1 -1
  47. package/dist/Stream.d.ts +198 -386
  48. package/dist/Stream.d.ts.map +1 -1
  49. package/dist/Stream.js +103 -59
  50. package/dist/Stream.js.map +1 -1
  51. package/dist/Trie.d.ts +18 -17
  52. package/dist/Trie.d.ts.map +1 -1
  53. package/dist/Trie.js +5 -5
  54. package/dist/Trie.js.map +1 -1
  55. package/dist/TxChunk.d.ts +37 -37
  56. package/dist/TxChunk.d.ts.map +1 -1
  57. package/dist/TxChunk.js +3 -3
  58. package/dist/TxChunk.js.map +1 -1
  59. package/dist/TxDeferred.d.ts +328 -0
  60. package/dist/TxDeferred.d.ts.map +1 -0
  61. package/dist/TxDeferred.js +196 -0
  62. package/dist/TxDeferred.js.map +1 -0
  63. package/dist/TxHashMap.d.ts +84 -83
  64. package/dist/TxHashMap.d.ts.map +1 -1
  65. package/dist/TxHashMap.js +24 -24
  66. package/dist/TxHashMap.js.map +1 -1
  67. package/dist/TxHashSet.d.ts +35 -35
  68. package/dist/TxHashSet.d.ts.map +1 -1
  69. package/dist/TxHashSet.js +14 -14
  70. package/dist/TxHashSet.js.map +1 -1
  71. package/dist/TxPriorityQueue.d.ts +609 -0
  72. package/dist/TxPriorityQueue.d.ts.map +1 -0
  73. package/dist/TxPriorityQueue.js +415 -0
  74. package/dist/TxPriorityQueue.js.map +1 -0
  75. package/dist/TxPubSub.d.ts +585 -0
  76. package/dist/TxPubSub.d.ts.map +1 -0
  77. package/dist/TxPubSub.js +521 -0
  78. package/dist/TxPubSub.js.map +1 -0
  79. package/dist/TxQueue.d.ts +32 -32
  80. package/dist/TxQueue.d.ts.map +1 -1
  81. package/dist/TxQueue.js +26 -26
  82. package/dist/TxQueue.js.map +1 -1
  83. package/dist/TxReentrantLock.d.ts +523 -0
  84. package/dist/TxReentrantLock.d.ts.map +1 -0
  85. package/dist/TxReentrantLock.js +504 -0
  86. package/dist/TxReentrantLock.js.map +1 -0
  87. package/dist/TxRef.d.ts +34 -34
  88. package/dist/TxRef.d.ts.map +1 -1
  89. package/dist/TxRef.js +21 -14
  90. package/dist/TxRef.js.map +1 -1
  91. package/dist/TxSemaphore.d.ts +8 -8
  92. package/dist/TxSemaphore.d.ts.map +1 -1
  93. package/dist/TxSemaphore.js +7 -7
  94. package/dist/TxSemaphore.js.map +1 -1
  95. package/dist/TxSubscriptionRef.d.ts +508 -0
  96. package/dist/TxSubscriptionRef.d.ts.map +1 -0
  97. package/dist/TxSubscriptionRef.js +293 -0
  98. package/dist/TxSubscriptionRef.js.map +1 -0
  99. package/dist/index.d.ts +40 -0
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +40 -0
  102. package/dist/index.js.map +1 -1
  103. package/dist/internal/effect.js +99 -42
  104. package/dist/internal/effect.js.map +1 -1
  105. package/dist/internal/hashMap.js +3 -2
  106. package/dist/internal/hashMap.js.map +1 -1
  107. package/dist/internal/trie.js +5 -4
  108. package/dist/internal/trie.js.map +1 -1
  109. package/dist/unstable/ai/Tool.d.ts.map +1 -1
  110. package/dist/unstable/ai/Tool.js +0 -9
  111. package/dist/unstable/ai/Tool.js.map +1 -1
  112. package/dist/unstable/cli/Command.d.ts +1 -1
  113. package/dist/unstable/cli/Command.d.ts.map +1 -1
  114. package/dist/unstable/cli/Command.js +1 -1
  115. package/dist/unstable/cli/Command.js.map +1 -1
  116. package/dist/unstable/cluster/K8sHttpClient.js +4 -4
  117. package/dist/unstable/cluster/K8sHttpClient.js.map +1 -1
  118. package/dist/unstable/cluster/Sharding.js +1 -1
  119. package/dist/unstable/cluster/Sharding.js.map +1 -1
  120. package/dist/unstable/encoding/Sse.js +1 -1
  121. package/dist/unstable/encoding/Sse.js.map +1 -1
  122. package/dist/unstable/rpc/RpcServer.d.ts.map +1 -1
  123. package/dist/unstable/rpc/RpcServer.js +1 -2
  124. package/dist/unstable/rpc/RpcServer.js.map +1 -1
  125. package/dist/unstable/socket/Socket.d.ts.map +1 -1
  126. package/dist/unstable/socket/Socket.js +3 -3
  127. package/dist/unstable/socket/Socket.js.map +1 -1
  128. package/package.json +1 -1
  129. package/src/Array.ts +190 -342
  130. package/src/Cache.ts +6 -5
  131. package/src/Channel.ts +506 -102
  132. package/src/Chunk.ts +81 -268
  133. package/src/Effect.ts +437 -518
  134. package/src/Filter.ts +0 -57
  135. package/src/HashMap.ts +15 -14
  136. package/src/Iterable.ts +105 -50
  137. package/src/Option.ts +30 -20
  138. package/src/Pull.ts +1 -1
  139. package/src/Record.ts +43 -152
  140. package/src/Sink.ts +75 -23
  141. package/src/Stream.ts +442 -502
  142. package/src/Trie.ts +18 -17
  143. package/src/TxChunk.ts +72 -53
  144. package/src/TxDeferred.ts +394 -0
  145. package/src/TxHashMap.ts +332 -285
  146. package/src/TxHashSet.ts +111 -116
  147. package/src/TxPriorityQueue.ts +767 -0
  148. package/src/TxPubSub.ts +789 -0
  149. package/src/TxQueue.ts +241 -251
  150. package/src/TxReentrantLock.ts +753 -0
  151. package/src/TxRef.ts +50 -38
  152. package/src/TxSemaphore.ts +29 -32
  153. package/src/TxSubscriptionRef.ts +639 -0
  154. package/src/index.ts +45 -0
  155. package/src/internal/effect.ts +368 -163
  156. package/src/internal/hashMap.ts +7 -5
  157. package/src/internal/trie.ts +16 -9
  158. package/src/unstable/ai/Tool.ts +0 -9
  159. package/src/unstable/cli/Command.ts +6 -4
  160. package/src/unstable/cluster/K8sHttpClient.ts +4 -4
  161. package/src/unstable/cluster/Sharding.ts +1 -1
  162. package/src/unstable/encoding/Sse.ts +1 -1
  163. package/src/unstable/rpc/RpcServer.ts +1 -7
  164. package/src/unstable/socket/Socket.ts +9 -11
@@ -0,0 +1,394 @@
1
+ /**
2
+ * A transactional deferred value — a write-once cell that can be read within transactions.
3
+ * Readers retry until a value is set; once set, the value is immutable.
4
+ *
5
+ * @since 4.0.0
6
+ */
7
+
8
+ import * as Effect from "./Effect.ts"
9
+ import { dual } from "./Function.ts"
10
+ import type { Inspectable } from "./Inspectable.ts"
11
+ import { NodeInspectSymbol, toJson } from "./Inspectable.ts"
12
+ import type { Option } from "./Option.ts"
13
+ import * as O from "./Option.ts"
14
+ import type { Pipeable } from "./Pipeable.ts"
15
+ import { pipeArguments } from "./Pipeable.ts"
16
+ import type { Result } from "./Result.ts"
17
+ import * as Res from "./Result.ts"
18
+ import * as TxRef from "./TxRef.ts"
19
+
20
+ const TypeId = "~effect/transactions/TxDeferred"
21
+
22
+ /**
23
+ * A transactional deferred — a write-once cell readable within transactions.
24
+ *
25
+ * Readers block (retry the transaction) until a value is committed.
26
+ * Writers succeed only on the first call; subsequent writes return `false`.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import { Effect, TxDeferred } from "effect"
31
+ *
32
+ * const program = Effect.gen(function*() {
33
+ * const deferred = yield* TxDeferred.make<number>()
34
+ *
35
+ * // Complete the deferred
36
+ * const first = yield* TxDeferred.succeed(deferred, 42)
37
+ * console.log(first) // true
38
+ *
39
+ * // Second write is a no-op
40
+ * const second = yield* TxDeferred.succeed(deferred, 99)
41
+ * console.log(second) // false
42
+ *
43
+ * // Read the value
44
+ * const value = yield* TxDeferred.await(deferred)
45
+ * console.log(value) // 42
46
+ * })
47
+ * ```
48
+ *
49
+ * @since 4.0.0
50
+ * @category models
51
+ */
52
+ export interface TxDeferred<in out A, in out E = never> extends Inspectable, Pipeable {
53
+ readonly [TypeId]: typeof TypeId
54
+ readonly ref: TxRef.TxRef<Option<Result<A, E>>>
55
+ }
56
+
57
+ const TxDeferredProto: Omit<TxDeferred<unknown, unknown>, typeof TypeId | "ref"> = {
58
+ [NodeInspectSymbol](this: TxDeferred<unknown, unknown>) {
59
+ return toJson(this)
60
+ },
61
+ toJSON(this: TxDeferred<unknown, unknown>) {
62
+ return {
63
+ _id: "TxDeferred"
64
+ }
65
+ },
66
+ pipe() {
67
+ return pipeArguments(this, arguments)
68
+ }
69
+ }
70
+
71
+ const makeTxDeferred = <A, E>(ref: TxRef.TxRef<Option<Result<A, E>>>): TxDeferred<A, E> => {
72
+ const self = Object.create(TxDeferredProto)
73
+ self[TypeId] = TypeId
74
+ self.ref = ref
75
+ return self
76
+ }
77
+
78
+ /**
79
+ * Creates a new empty `TxDeferred`.
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * import { Effect, Option, TxDeferred } from "effect"
84
+ *
85
+ * const program = Effect.gen(function*() {
86
+ * const deferred = yield* TxDeferred.make<string, Error>()
87
+ * const state = yield* TxDeferred.poll(deferred)
88
+ * console.log(Option.isNone(state)) // true
89
+ * })
90
+ * ```
91
+ *
92
+ * @since 4.0.0
93
+ * @category constructors
94
+ */
95
+ export const make = <A, E = never>(): Effect.Effect<TxDeferred<A, E>, never, Effect.Transaction> =>
96
+ Effect.map(TxRef.make<Option<Result<A, E>>>(O.none()), makeTxDeferred)
97
+
98
+ /**
99
+ * Reads the deferred value. Retries the transaction if the deferred has not
100
+ * been completed yet.
101
+ *
102
+ * @example
103
+ * ```ts
104
+ * import { Effect, TxDeferred } from "effect"
105
+ *
106
+ * const program = Effect.gen(function*() {
107
+ * const deferred = yield* TxDeferred.make<number>()
108
+ * yield* TxDeferred.succeed(deferred, 42)
109
+ * const value = yield* TxDeferred.await(deferred)
110
+ * console.log(value) // 42
111
+ * })
112
+ * ```
113
+ *
114
+ * @since 4.0.0
115
+ * @category getters
116
+ */
117
+ const await_ = <A, E>(self: TxDeferred<A, E>): Effect.Effect<A, E, Effect.Transaction> =>
118
+ Effect.gen(function*() {
119
+ const option = yield* TxRef.get(self.ref)
120
+ if (O.isNone(option)) {
121
+ return yield* Effect.retryTransaction
122
+ }
123
+ return Res.isSuccess(option.value)
124
+ ? option.value.success
125
+ : yield* Effect.fail(option.value.failure)
126
+ })
127
+
128
+ export {
129
+ /**
130
+ * Reads the deferred value. Retries the transaction if the deferred has not
131
+ * been completed yet.
132
+ *
133
+ * @since 4.0.0
134
+ * @category getters
135
+ */
136
+ await_ as await
137
+ }
138
+
139
+ /**
140
+ * Reads the current state of the deferred without retrying. Returns `None` if
141
+ * not yet completed.
142
+ *
143
+ * @example
144
+ * ```ts
145
+ * import { Effect, Option, Result, TxDeferred } from "effect"
146
+ *
147
+ * const program = Effect.gen(function*() {
148
+ * const deferred = yield* TxDeferred.make<number>()
149
+ * const before = yield* TxDeferred.poll(deferred)
150
+ * console.log(Option.isNone(before)) // true
151
+ *
152
+ * yield* TxDeferred.succeed(deferred, 42)
153
+ * const after = yield* TxDeferred.poll(deferred)
154
+ * console.log(after) // Some(Success(42))
155
+ * })
156
+ * ```
157
+ *
158
+ * @since 4.0.0
159
+ * @category getters
160
+ */
161
+ export const poll = <A, E>(self: TxDeferred<A, E>): Effect.Effect<Option<Result<A, E>>, never, Effect.Transaction> =>
162
+ TxRef.get(self.ref)
163
+
164
+ /**
165
+ * Completes the deferred with a `Result`. Returns `true` if this was the first
166
+ * completion, `false` if already completed.
167
+ *
168
+ * @example
169
+ * ```ts
170
+ * import { Effect, Result, TxDeferred } from "effect"
171
+ *
172
+ * const program = Effect.gen(function*() {
173
+ * const deferred = yield* TxDeferred.make<number, string>()
174
+ * const first = yield* TxDeferred.done(deferred, Result.succeed(42))
175
+ * console.log(first) // true
176
+ * const second = yield* TxDeferred.done(deferred, Result.succeed(99))
177
+ * console.log(second) // false
178
+ * })
179
+ * ```
180
+ *
181
+ * @since 4.0.0
182
+ * @category mutations
183
+ */
184
+ export const done: {
185
+ /**
186
+ * Completes the deferred with a `Result`. Returns `true` if this was the first
187
+ * completion, `false` if already completed.
188
+ *
189
+ * @example
190
+ * ```ts
191
+ * import { Effect, Result, TxDeferred } from "effect"
192
+ *
193
+ * const program = Effect.gen(function*() {
194
+ * const deferred = yield* TxDeferred.make<number, string>()
195
+ * const first = yield* TxDeferred.done(deferred, Result.succeed(42))
196
+ * console.log(first) // true
197
+ * const second = yield* TxDeferred.done(deferred, Result.succeed(99))
198
+ * console.log(second) // false
199
+ * })
200
+ * ```
201
+ *
202
+ * @since 4.0.0
203
+ * @category mutations
204
+ */
205
+ <A, E>(result: Result<A, E>): (self: TxDeferred<A, E>) => Effect.Effect<boolean, never, Effect.Transaction>
206
+ /**
207
+ * Completes the deferred with a `Result`. Returns `true` if this was the first
208
+ * completion, `false` if already completed.
209
+ *
210
+ * @example
211
+ * ```ts
212
+ * import { Effect, Result, TxDeferred } from "effect"
213
+ *
214
+ * const program = Effect.gen(function*() {
215
+ * const deferred = yield* TxDeferred.make<number, string>()
216
+ * const first = yield* TxDeferred.done(deferred, Result.succeed(42))
217
+ * console.log(first) // true
218
+ * const second = yield* TxDeferred.done(deferred, Result.succeed(99))
219
+ * console.log(second) // false
220
+ * })
221
+ * ```
222
+ *
223
+ * @since 4.0.0
224
+ * @category mutations
225
+ */
226
+ <A, E>(self: TxDeferred<A, E>, result: Result<A, E>): Effect.Effect<boolean, never, Effect.Transaction>
227
+ } = dual(
228
+ 2,
229
+ <A, E>(self: TxDeferred<A, E>, result: Result<A, E>): Effect.Effect<boolean, never, Effect.Transaction> =>
230
+ TxRef.modify(self.ref, (current) => {
231
+ if (O.isSome(current)) {
232
+ return [false, current]
233
+ }
234
+ return [true, O.some(result)]
235
+ })
236
+ )
237
+
238
+ /**
239
+ * Completes the deferred with a success value. Returns `true` if this was the
240
+ * first completion, `false` if already completed.
241
+ *
242
+ * @example
243
+ * ```ts
244
+ * import { Effect, TxDeferred } from "effect"
245
+ *
246
+ * const program = Effect.gen(function*() {
247
+ * const deferred = yield* TxDeferred.make<number>()
248
+ * const first = yield* TxDeferred.succeed(deferred, 42)
249
+ * console.log(first) // true
250
+ * const second = yield* TxDeferred.succeed(deferred, 99)
251
+ * console.log(second) // false
252
+ * })
253
+ * ```
254
+ *
255
+ * @since 4.0.0
256
+ * @category mutations
257
+ */
258
+ export const succeed: {
259
+ /**
260
+ * Completes the deferred with a success value. Returns `true` if this was the
261
+ * first completion, `false` if already completed.
262
+ *
263
+ * @example
264
+ * ```ts
265
+ * import { Effect, TxDeferred } from "effect"
266
+ *
267
+ * const program = Effect.gen(function*() {
268
+ * const deferred = yield* TxDeferred.make<number>()
269
+ * const first = yield* TxDeferred.succeed(deferred, 42)
270
+ * console.log(first) // true
271
+ * const second = yield* TxDeferred.succeed(deferred, 99)
272
+ * console.log(second) // false
273
+ * })
274
+ * ```
275
+ *
276
+ * @since 4.0.0
277
+ * @category mutations
278
+ */
279
+ <A>(value: A): <E>(self: TxDeferred<A, E>) => Effect.Effect<boolean, never, Effect.Transaction>
280
+ /**
281
+ * Completes the deferred with a success value. Returns `true` if this was the
282
+ * first completion, `false` if already completed.
283
+ *
284
+ * @example
285
+ * ```ts
286
+ * import { Effect, TxDeferred } from "effect"
287
+ *
288
+ * const program = Effect.gen(function*() {
289
+ * const deferred = yield* TxDeferred.make<number>()
290
+ * const first = yield* TxDeferred.succeed(deferred, 42)
291
+ * console.log(first) // true
292
+ * const second = yield* TxDeferred.succeed(deferred, 99)
293
+ * console.log(second) // false
294
+ * })
295
+ * ```
296
+ *
297
+ * @since 4.0.0
298
+ * @category mutations
299
+ */
300
+ <A, E>(self: TxDeferred<A, E>, value: A): Effect.Effect<boolean, never, Effect.Transaction>
301
+ } = dual(
302
+ 2,
303
+ <A, E>(self: TxDeferred<A, E>, value: A): Effect.Effect<boolean, never, Effect.Transaction> =>
304
+ done(self, Res.succeed(value))
305
+ )
306
+
307
+ /**
308
+ * Completes the deferred with a failure. Returns `true` if this was the first
309
+ * completion, `false` if already completed.
310
+ *
311
+ * @example
312
+ * ```ts
313
+ * import { Effect, TxDeferred } from "effect"
314
+ *
315
+ * const program = Effect.gen(function*() {
316
+ * const deferred = yield* TxDeferred.make<number, string>()
317
+ * const first = yield* TxDeferred.fail(deferred, "boom")
318
+ * console.log(first) // true
319
+ * const second = yield* TxDeferred.fail(deferred, "boom2")
320
+ * console.log(second) // false
321
+ * })
322
+ * ```
323
+ *
324
+ * @since 4.0.0
325
+ * @category mutations
326
+ */
327
+ export const fail: {
328
+ /**
329
+ * Completes the deferred with a failure. Returns `true` if this was the first
330
+ * completion, `false` if already completed.
331
+ *
332
+ * @example
333
+ * ```ts
334
+ * import { Effect, TxDeferred } from "effect"
335
+ *
336
+ * const program = Effect.gen(function*() {
337
+ * const deferred = yield* TxDeferred.make<number, string>()
338
+ * const first = yield* TxDeferred.fail(deferred, "boom")
339
+ * console.log(first) // true
340
+ * const second = yield* TxDeferred.fail(deferred, "boom2")
341
+ * console.log(second) // false
342
+ * })
343
+ * ```
344
+ *
345
+ * @since 4.0.0
346
+ * @category mutations
347
+ */
348
+ <E>(error: E): <A>(self: TxDeferred<A, E>) => Effect.Effect<boolean, never, Effect.Transaction>
349
+ /**
350
+ * Completes the deferred with a failure. Returns `true` if this was the first
351
+ * completion, `false` if already completed.
352
+ *
353
+ * @example
354
+ * ```ts
355
+ * import { Effect, TxDeferred } from "effect"
356
+ *
357
+ * const program = Effect.gen(function*() {
358
+ * const deferred = yield* TxDeferred.make<number, string>()
359
+ * const first = yield* TxDeferred.fail(deferred, "boom")
360
+ * console.log(first) // true
361
+ * const second = yield* TxDeferred.fail(deferred, "boom2")
362
+ * console.log(second) // false
363
+ * })
364
+ * ```
365
+ *
366
+ * @since 4.0.0
367
+ * @category mutations
368
+ */
369
+ <A, E>(self: TxDeferred<A, E>, error: E): Effect.Effect<boolean, never, Effect.Transaction>
370
+ } = dual(
371
+ 2,
372
+ <A, E>(self: TxDeferred<A, E>, error: E): Effect.Effect<boolean, never, Effect.Transaction> =>
373
+ done(self, Res.fail(error))
374
+ )
375
+
376
+ /**
377
+ * Determines if the provided value is a `TxDeferred`.
378
+ *
379
+ * @example
380
+ * ```ts
381
+ * import { Effect, TxDeferred } from "effect"
382
+ *
383
+ * const program = Effect.gen(function*() {
384
+ * const deferred = yield* TxDeferred.make<number>()
385
+ * console.log(TxDeferred.isTxDeferred(deferred)) // true
386
+ * console.log(TxDeferred.isTxDeferred("not a deferred")) // false
387
+ * })
388
+ * ```
389
+ *
390
+ * @since 4.0.0
391
+ * @category guards
392
+ */
393
+ export const isTxDeferred = (u: unknown): u is TxDeferred<unknown, unknown> =>
394
+ typeof u === "object" && u !== null && TypeId in u