@livestore/utils 0.3.2-dev.0 → 0.3.2-dev.10

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 (110) hide show
  1. package/dist/.tsbuildinfo.json +1 -1
  2. package/dist/NoopTracer.d.ts.map +1 -1
  3. package/dist/NoopTracer.js.map +1 -1
  4. package/dist/base64.d.ts.map +1 -1
  5. package/dist/base64.js +0 -1
  6. package/dist/base64.js.map +1 -1
  7. package/dist/bun/mod.d.ts +0 -2
  8. package/dist/bun/mod.d.ts.map +1 -1
  9. package/dist/bun/mod.js +0 -6
  10. package/dist/bun/mod.js.map +1 -1
  11. package/dist/cuid/cuid.browser.d.ts.map +1 -1
  12. package/dist/cuid/cuid.browser.js +0 -1
  13. package/dist/cuid/cuid.browser.js.map +1 -1
  14. package/dist/cuid/cuid.node.d.ts.map +1 -1
  15. package/dist/cuid/cuid.node.js +0 -1
  16. package/dist/cuid/cuid.node.js.map +1 -1
  17. package/dist/effect/Effect.d.ts.map +1 -1
  18. package/dist/effect/Effect.js +3 -3
  19. package/dist/effect/Effect.js.map +1 -1
  20. package/dist/effect/Scheduler.d.ts.map +1 -1
  21. package/dist/effect/Scheduler.js +0 -1
  22. package/dist/effect/Scheduler.js.map +1 -1
  23. package/dist/effect/Schema/debug-diff.test.js +1 -1
  24. package/dist/effect/Schema/index.d.ts +2 -2
  25. package/dist/effect/Schema/index.js +3 -3
  26. package/dist/effect/Schema/index.js.map +1 -1
  27. package/dist/effect/Subscribable.d.ts.map +1 -1
  28. package/dist/effect/Subscribable.js +2 -3
  29. package/dist/effect/Subscribable.js.map +1 -1
  30. package/dist/effect/WebChannel/WebChannel.d.ts +3 -3
  31. package/dist/effect/WebChannel/WebChannel.js +5 -5
  32. package/dist/effect/WebChannel/WebChannel.test.js +1 -1
  33. package/dist/effect/WebChannel/broadcastChannelWithAck.d.ts +2 -2
  34. package/dist/effect/WebChannel/broadcastChannelWithAck.js +2 -2
  35. package/dist/effect/WebChannel/mod.d.ts +3 -3
  36. package/dist/effect/WebChannel/mod.d.ts.map +1 -1
  37. package/dist/effect/WebChannel/mod.js +3 -3
  38. package/dist/effect/WebChannel/mod.js.map +1 -1
  39. package/dist/effect/WebLock.js.map +1 -1
  40. package/dist/effect/WebSocket.test.js +1 -1
  41. package/dist/effect/index.d.ts +22 -23
  42. package/dist/effect/index.d.ts.map +1 -1
  43. package/dist/effect/index.js +25 -26
  44. package/dist/effect/index.js.map +1 -1
  45. package/dist/env.js +1 -1
  46. package/dist/fast-deep-equal.d.ts.map +1 -1
  47. package/dist/fast-deep-equal.js +0 -1
  48. package/dist/fast-deep-equal.js.map +1 -1
  49. package/dist/global.d.ts +3 -0
  50. package/dist/global.d.ts.map +1 -1
  51. package/dist/global.js.map +1 -1
  52. package/dist/index.d.ts +83 -42
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +19 -16
  55. package/dist/index.js.map +1 -1
  56. package/dist/misc.d.ts.map +1 -1
  57. package/dist/misc.js +0 -1
  58. package/dist/misc.js.map +1 -1
  59. package/dist/mod.d.ts +82 -0
  60. package/dist/mod.d.ts.map +1 -0
  61. package/dist/mod.js +167 -0
  62. package/dist/mod.js.map +1 -0
  63. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/ChildProcessRunner.test.js +2 -2
  64. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/schema.d.ts +2 -2
  65. package/dist/node/ChildProcessRunner/ChildProcessRunnerTest/serializedWorker.js +3 -3
  66. package/dist/node/mod.d.ts +4 -4
  67. package/dist/node/mod.d.ts.map +1 -1
  68. package/dist/node/mod.js +5 -5
  69. package/dist/node/mod.js.map +1 -1
  70. package/dist/object/index.d.ts +3 -2
  71. package/dist/object/index.d.ts.map +1 -1
  72. package/dist/object/index.js +3 -2
  73. package/dist/object/index.js.map +1 -1
  74. package/dist/object/stringify-object.d.ts +9 -0
  75. package/dist/object/stringify-object.d.ts.map +1 -0
  76. package/dist/object/stringify-object.js +27 -0
  77. package/dist/object/stringify-object.js.map +1 -0
  78. package/dist/object/stringify-object.test.d.ts +2 -0
  79. package/dist/object/stringify-object.test.d.ts.map +1 -0
  80. package/dist/object/stringify-object.test.js +38 -0
  81. package/dist/object/stringify-object.test.js.map +1 -0
  82. package/package.json +9 -35
  83. package/src/NoopTracer.ts +0 -1
  84. package/src/base64.ts +0 -1
  85. package/src/bun/mod.ts +0 -8
  86. package/src/cuid/cuid.browser.ts +0 -1
  87. package/src/cuid/cuid.node.ts +0 -1
  88. package/src/effect/Effect.ts +6 -3
  89. package/src/effect/Scheduler.ts +0 -1
  90. package/src/effect/Schema/debug-diff.test.ts +2 -2
  91. package/src/effect/Schema/index.ts +3 -3
  92. package/src/effect/Subscribable.ts +6 -5
  93. package/src/effect/WebChannel/WebChannel.test.ts +1 -1
  94. package/src/effect/WebChannel/WebChannel.ts +5 -5
  95. package/src/effect/WebChannel/broadcastChannelWithAck.ts +3 -3
  96. package/src/effect/WebChannel/mod.ts +3 -3
  97. package/src/effect/WebLock.ts +1 -1
  98. package/src/effect/WebSocket.test.ts +1 -1
  99. package/src/effect/index.ts +104 -110
  100. package/src/env.ts +1 -1
  101. package/src/fast-deep-equal.ts +0 -2
  102. package/src/global.ts +4 -0
  103. package/src/misc.ts +0 -1
  104. package/src/{index.ts → mod.ts} +21 -16
  105. package/src/node/ChildProcessRunner/ChildProcessRunnerTest/ChildProcessRunner.test.ts +3 -3
  106. package/src/node/ChildProcessRunner/ChildProcessRunnerTest/serializedWorker.ts +3 -3
  107. package/src/node/mod.ts +6 -6
  108. package/src/object/index.ts +3 -2
  109. package/src/object/stringify-object.test.ts +44 -0
  110. package/src/object/stringify-object.ts +27 -0
@@ -1,10 +1,10 @@
1
1
  import { Deferred, Either, Exit, GlobalValue, identity, Option, PubSub, Queue, Scope } from 'effect'
2
2
  import type { DurationInput } from 'effect/Duration'
3
3
 
4
- import { shouldNeverHappen } from '../../misc.js'
5
- import * as Effect from '../Effect.js'
6
- import * as Schema from '../Schema/index.js'
7
- import * as Stream from '../Stream.js'
4
+ import { shouldNeverHappen } from '../../misc.ts'
5
+ import * as Effect from '../Effect.ts'
6
+ import * as Schema from '../Schema/index.ts'
7
+ import * as Stream from '../Stream.ts'
8
8
  import {
9
9
  DebugPingMessage,
10
10
  type InputSchema,
@@ -15,7 +15,7 @@ import {
15
15
  WebChannelPing,
16
16
  WebChannelPong,
17
17
  WebChannelSymbol,
18
- } from './common.js'
18
+ } from './common.ts'
19
19
 
20
20
  export const shutdown = <MsgListen, MsgSend>(webChannel: WebChannel<MsgListen, MsgSend>): Effect.Effect<void> =>
21
21
  Deferred.done(webChannel.closedDeferred, Exit.void)
@@ -1,8 +1,8 @@
1
1
  import { Deferred, Exit, Predicate, Queue, Schema, Scope, Stream } from 'effect'
2
2
 
3
- import * as Effect from '../Effect.js'
4
- import type { InputSchema, WebChannel } from './common.js'
5
- import { listenToDebugPing, mapSchema, WebChannelSymbol } from './common.js'
3
+ import * as Effect from '../Effect.ts'
4
+ import type { InputSchema, WebChannel } from './common.ts'
5
+ import { listenToDebugPing, mapSchema, WebChannelSymbol } from './common.ts'
6
6
 
7
7
  const ConnectMessage = Schema.TaggedStruct('ConnectMessage', {
8
8
  from: Schema.String,
@@ -1,3 +1,3 @@
1
- export * from './WebChannel.js'
2
- export * from './broadcastChannelWithAck.js'
3
- export * from './common.js'
1
+ export * from './broadcastChannelWithAck.ts'
2
+ export * from './common.ts'
3
+ export * from './WebChannel.ts'
@@ -35,7 +35,7 @@ export const withLock =
35
35
 
36
36
  // TODO also propagate Effect interruption to the execution
37
37
  return Runtime.runPromiseExit(runtime)(eff)
38
- })
38
+ }) as unknown as Promise<Exit.Exit<A, E>>
39
39
  },
40
40
  catch: (err) => err as any as E,
41
41
  })
@@ -2,7 +2,7 @@ import { FetchHttpClient } from '@effect/platform'
2
2
  import * as Vitest from '@effect/vitest'
3
3
  import { Effect, Exit } from 'effect'
4
4
 
5
- import { makeWebSocket } from './WebSocket.js'
5
+ import { makeWebSocket } from './WebSocket.ts'
6
6
 
7
7
  Vitest.describe('WebSocket', () => {
8
8
  Vitest.scopedLive(
@@ -1,137 +1,131 @@
1
- import '../global.js'
1
+ import '../global.ts'
2
2
 
3
+ export * as OtelTracer from '@effect/opentelemetry/Tracer'
3
4
  export {
4
- Scope,
5
- Ref,
6
- SynchronizedRef,
7
- Queue,
5
+ Command,
6
+ CommandExecutor,
7
+ Error as PlatformError,
8
+ FetchHttpClient,
9
+ FileSystem,
10
+ Headers,
11
+ HttpClient,
12
+ HttpClientError,
13
+ HttpClientRequest,
14
+ HttpClientResponse,
15
+ HttpMiddleware,
16
+ HttpRouter,
17
+ HttpServer,
18
+ HttpServerRequest,
19
+ HttpServerResponse,
20
+ KeyValueStore,
21
+ Socket,
22
+ Terminal,
23
+ Transferable,
24
+ UrlParams,
25
+ Worker,
26
+ WorkerError,
27
+ WorkerRunner,
28
+ } from '@effect/platform'
29
+ export { BrowserWorker, BrowserWorkerRunner } from '@effect/platform-browser'
30
+ export {
31
+ Rpc,
32
+ RpcClient,
33
+ RpcGroup,
34
+ RpcMessage,
35
+ RpcMiddleware,
36
+ RpcSchema,
37
+ RpcSerialization,
38
+ RpcServer,
39
+ RpcTest,
40
+ RpcWorker,
41
+ } from '@effect/rpc'
42
+ export * as StandardSchema from '@standard-schema/spec'
43
+ export {
44
+ Array as ReadonlyArray,
45
+ Brand,
46
+ Cache,
47
+ Cause,
48
+ Channel,
49
+ Chunk,
50
+ // Logger,
51
+ Config,
52
+ Context,
53
+ Data,
54
+ Deferred,
55
+ Duration,
56
+ Either,
57
+ Equal,
58
+ ExecutionStrategy,
59
+ Exit,
8
60
  Fiber,
61
+ FiberHandle,
9
62
  FiberId,
10
- FiberSet,
11
63
  FiberMap,
12
- FiberHandle,
13
- Inspectable,
14
- RuntimeFlags,
15
- PubSub,
16
- Exit,
17
- Cause,
18
- Runtime,
19
64
  FiberRef,
20
65
  FiberRefs,
21
66
  FiberRefsPatch,
22
- Deferred,
23
- Metric,
24
- MetricState,
25
- Request,
26
- Tracer,
27
- Context,
28
- Data,
29
- Either,
30
- Brand,
67
+ FiberSet,
68
+ GlobalValue,
31
69
  Hash,
32
- Equal,
33
- Chunk,
34
- Duration,
35
- Array as ReadonlyArray,
36
- Record as ReadonlyRecord,
37
- SortedMap,
38
70
  HashMap,
39
71
  HashSet,
72
+ Inspectable,
73
+ identity,
74
+ Layer,
75
+ List,
76
+ LogLevel,
77
+ LogSpan,
78
+ Mailbox,
40
79
  ManagedRuntime,
41
- MutableHashSet,
80
+ Match,
81
+ Metric,
82
+ MetricState,
42
83
  MutableHashMap,
43
- TQueue,
84
+ MutableHashSet,
44
85
  Option,
45
- LogLevel,
46
- // Logger,
47
- Config,
48
- Layer,
49
- STM,
50
- TRef,
51
- Channel,
86
+ ParseResult,
52
87
  Predicate,
88
+ Pretty,
89
+ PrimaryKey,
90
+ PubSub,
53
91
  // Subscribable,
54
92
  pipe,
55
- identity,
56
- GlobalValue,
57
- Match,
93
+ Queue,
94
+ Record as ReadonlyRecord,
95
+ Ref,
96
+ Request,
97
+ Runtime,
98
+ RuntimeFlags,
99
+ Scope,
100
+ SortedMap,
101
+ STM,
102
+ SynchronizedRef,
58
103
  TestServices,
59
- Mailbox,
60
- ExecutionStrategy,
61
- PrimaryKey,
104
+ TQueue,
105
+ TRef,
106
+ Tracer,
62
107
  Types,
63
- Cache,
64
108
  } from 'effect'
65
-
66
- export * as StandardSchema from '@standard-schema/spec'
67
-
68
109
  export { dual } from 'effect/Function'
69
-
70
- export * as Stream from './Stream.js'
71
-
72
- export * as BucketQueue from './BucketQueue.js'
73
-
74
- export * as SubscriptionRef from './SubscriptionRef.js'
75
- export * as Subscribable from './Subscribable.js'
76
-
77
- export * as Logger from './Logger.js'
78
-
79
- export * as WebChannel from './WebChannel/mod.js'
80
- export * as WebSocket from './WebSocket.js'
81
-
82
- export * as SchemaAST from 'effect/SchemaAST'
83
110
  export { TreeFormatter } from 'effect/ParseResult'
84
- export { ParseResult, Pretty } from 'effect'
85
111
  export type { Serializable, SerializableWithResult } from 'effect/Schema'
86
- export * as Schema from './Schema/index.js'
87
- export * as OtelTracer from '@effect/opentelemetry/Tracer'
88
- export * as TaskTracing from './TaskTracing.js'
89
-
90
- export {
91
- Rpc,
92
- RpcGroup,
93
- RpcClient,
94
- RpcMessage,
95
- RpcSchema,
96
- RpcMiddleware,
97
- RpcServer,
98
- RpcSerialization,
99
- RpcTest,
100
- RpcWorker,
101
- } from '@effect/rpc'
102
112
 
103
- export {
104
- Transferable,
105
- FileSystem,
106
- Worker,
107
- WorkerError,
108
- WorkerRunner,
109
- Terminal,
110
- HttpServer,
111
- HttpClient,
112
- HttpClientError,
113
- HttpClientRequest,
114
- HttpClientResponse,
115
- FetchHttpClient,
116
- Socket,
117
- UrlParams,
118
- HttpServerRequest,
119
- Headers,
120
- HttpMiddleware,
121
- HttpRouter,
122
- HttpServerResponse,
123
- Command,
124
- CommandExecutor,
125
- KeyValueStore,
126
- Error as PlatformError,
127
- } from '@effect/platform'
128
- export { BrowserWorker, BrowserWorkerRunner } from '@effect/platform-browser'
113
+ export * as SchemaAST from 'effect/SchemaAST'
114
+ export * as BucketQueue from './BucketQueue.ts'
115
+ export * as Logger from './Logger.ts'
116
+ export * as Schema from './Schema/index.ts'
117
+ export * as Stream from './Stream.ts'
118
+ export * as Subscribable from './Subscribable.ts'
119
+ export * as SubscriptionRef from './SubscriptionRef.ts'
120
+ export * as TaskTracing from './TaskTracing.ts'
121
+ export * as WebChannel from './WebChannel/mod.ts'
122
+ export * as WebSocket from './WebSocket.ts'
129
123
 
130
124
  // export { DevTools as EffectDevtools } from '@effect/experimental'
131
125
 
132
- export * as Effect from './Effect.js'
133
- export * as Schedule from './Schedule.js'
134
- export * as Scheduler from './Scheduler.js'
135
- export * from './Error.js'
136
- export * as ServiceContext from './ServiceContext.js'
137
- export * as WebLock from './WebLock.js'
126
+ export * as Effect from './Effect.ts'
127
+ export * from './Error.ts'
128
+ export * as Schedule from './Schedule.ts'
129
+ export * as Scheduler from './Scheduler.ts'
130
+ export * as ServiceContext from './ServiceContext.ts'
131
+ export * as WebLock from './WebLock.ts'
package/src/env.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { envTruish } from './misc.js'
1
+ import { envTruish } from './misc.ts'
2
2
 
3
3
  export const env = (name: string): string | undefined => {
4
4
  if (typeof process !== 'undefined' && process.env !== undefined) {
@@ -1,5 +1,3 @@
1
- /* eslint-disable no-var */
2
-
3
1
  // Copied from fast-deep-equal
4
2
  // MIT License
5
3
 
package/src/global.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  declare global {
2
2
  export type TODO<_Reason extends string = 'unknown'> = any
3
+
4
+ interface ImportMeta {
5
+ readonly main: boolean
6
+ }
3
7
  }
4
8
 
5
9
  export {}
package/src/misc.ts CHANGED
@@ -37,7 +37,6 @@ export const tryAsFunctionAndNew = <TArg, TResult>(
37
37
  try {
38
38
  // @ts-expect-error try out as constructor
39
39
  return new fnOrConstructor(arg)
40
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
41
40
  } catch (_e) {
42
41
  // @ts-expect-error try out as function
43
42
  return fnOrConstructor(arg)
@@ -1,22 +1,22 @@
1
1
  export { default as prettyBytes } from 'pretty-bytes'
2
- export * as base64 from './base64.js'
3
- export * from './browser.js'
4
- export * from './Deferred.js'
5
- export * from './env.js'
6
- export * from './fast-deep-equal.js'
7
- export * from './guards.js'
8
- export * from './misc.js'
9
- export * from './NoopTracer.js'
10
- export * from './object/index.js'
11
- export * from './promise.js'
12
- export * from './set.js'
13
- export * from './string.js'
14
- export * from './time.js'
2
+ export * as base64 from './base64.ts'
3
+ export * from './browser.ts'
4
+ export * from './Deferred.ts'
5
+ export * from './env.ts'
6
+ export * from './fast-deep-equal.ts'
7
+ export * from './guards.ts'
8
+ export * from './misc.ts'
9
+ export * from './NoopTracer.ts'
10
+ export * from './object/index.ts'
11
+ export * from './promise.ts'
12
+ export * from './set.ts'
13
+ export * from './string.ts'
14
+ export * from './time.ts'
15
15
 
16
16
  import type * as otel from '@opentelemetry/api'
17
17
  import type { Types } from 'effect'
18
18
 
19
- import { objectToString } from './misc.js'
19
+ import { objectToString } from './misc.ts'
20
20
 
21
21
  export type Prettify<T> = T extends infer U ? { [K in keyof U]: Prettify<U[K]> } : never
22
22
 
@@ -73,6 +73,11 @@ export const recRemoveUndefinedValues = (val: any): void => {
73
73
  }
74
74
  }
75
75
 
76
+ /**
77
+ * Replace non-alphanumeric characters with a dash.
78
+ */
79
+ export const sluggify = (str: string, separator = '-') => str.replace(/[^a-zA-Z0-9]/g, separator)
80
+
76
81
  export const prop =
77
82
  <T extends {}, K extends keyof T>(key: K) =>
78
83
  (obj: T): T[K] =>
@@ -86,7 +91,7 @@ export const isReadonlyArray = <I, T>(value: ReadonlyArray<I> | T): value is Rea
86
91
  * Use this to make assertion at end of if-else chain that all members of a
87
92
  * union have been accounted for.
88
93
  */
89
- /* eslint-disable-next-line prefer-arrow/prefer-arrow-functions */
94
+
90
95
  export function casesHandled(unexpectedCase: never): never {
91
96
  // biome-ignore lint/suspicious/noDebugger: debugging
92
97
  debugger
@@ -228,4 +233,4 @@ export const isPromise = (value: any): value is Promise<unknown> => typeof value
228
233
 
229
234
  export const isIterable = <T>(value: any): value is Iterable<T> => typeof value?.[Symbol.iterator] === 'function'
230
235
 
231
- export { objectToString as errorToString } from './misc.js'
236
+ export { objectToString as errorToString } from './misc.ts'
@@ -5,9 +5,9 @@ import * as EffectWorker from '@effect/platform/Worker'
5
5
  import { assert, describe, it } from '@effect/vitest'
6
6
  import { Chunk, Effect, Stream } from 'effect'
7
7
 
8
- import * as ChildProcessWorker from '../ChildProcessWorker.js'
9
- import type { WorkerMessage } from './schema.js'
10
- import { GetPersonById, GetUserById, InitialMessage, Person, User } from './schema.js'
8
+ import * as ChildProcessWorker from '../ChildProcessWorker.ts'
9
+ import type { WorkerMessage } from './schema.ts'
10
+ import { GetPersonById, GetUserById, InitialMessage, Person, User } from './schema.ts'
11
11
 
12
12
  const WorkerLive = ChildProcessWorker.layer(() =>
13
13
  ChildProcess.fork(
@@ -2,9 +2,9 @@ import * as Runner from '@effect/platform/WorkerRunner'
2
2
  import { Context, Effect, Layer, Option, Stream } from 'effect'
3
3
 
4
4
  // import { NodeRuntime, NodeWorkerRunner } from '@effect/platform-node'
5
- import { PlatformNode } from '../../mod.js'
6
- import * as ChildProcessRunner from '../ChildProcessRunner.js'
7
- import { Person, User, WorkerMessage } from './schema.js'
5
+ import { PlatformNode } from '../../mod.ts'
6
+ import * as ChildProcessRunner from '../ChildProcessRunner.ts'
7
+ import { Person, User, WorkerMessage } from './schema.ts'
8
8
 
9
9
  interface Name {
10
10
  readonly _: unique symbol
package/src/node/mod.ts CHANGED
@@ -2,15 +2,15 @@ import * as http from 'node:http'
2
2
 
3
3
  import { Effect, Layer } from 'effect'
4
4
 
5
- import { OtelTracer, UnknownError } from '../effect/index.js'
6
- import { makeNoopTracer } from '../NoopTracer.js'
5
+ import { OtelTracer, UnknownError } from '../effect/index.ts'
6
+ import { makeNoopTracer } from '../NoopTracer.ts'
7
7
 
8
8
  export * as Cli from '@effect/cli'
9
- export * as PlatformNode from '@effect/platform-node'
10
9
  export * as SocketServer from '@effect/platform/SocketServer'
10
+ export * as PlatformNode from '@effect/platform-node'
11
11
 
12
- export * as ChildProcessRunner from './ChildProcessRunner/ChildProcessRunner.js'
13
- export * as ChildProcessWorker from './ChildProcessRunner/ChildProcessWorker.js'
12
+ export * as ChildProcessRunner from './ChildProcessRunner/ChildProcessRunner.ts'
13
+ export * as ChildProcessWorker from './ChildProcessRunner/ChildProcessWorker.ts'
14
14
 
15
15
  // Enable debug logging for OpenTelemetry
16
16
  // otel.diag.setLogger(new otel.DiagConsoleLogger(), otel.DiagLogLevel.ERROR)
@@ -47,7 +47,7 @@ export const OtelLiveDummy: Layer.Layer<OtelTracer.OtelTracer> = Layer.suspend((
47
47
 
48
48
  const TracingLive = Layer.unwrapEffect(Effect.map(OtelTracer.make, Layer.setTracer)).pipe(
49
49
  Layer.provideMerge(OtelTracerLive),
50
- ) as any as Layer.Layer<OtelTracer.OtelTracer>
50
+ )
51
51
 
52
52
  return TracingLive
53
53
  })
@@ -1,7 +1,8 @@
1
1
  import { pipe } from 'effect'
2
2
 
3
- export * from './pick.js'
4
- export * from './omit.js'
3
+ export * from './omit.ts'
4
+ export * from './pick.ts'
5
+ export * from './stringify-object.ts'
5
6
 
6
7
  type ValueOfRecord<R extends Record<any, any>> = R extends Record<any, infer V> ? V : never
7
8
 
@@ -0,0 +1,44 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { stringifyObject } from './stringify-object.ts'
3
+
4
+ describe('stringifyObject', () => {
5
+ it('stringifies a flat object', () => {
6
+ const obj = { a: 1, b: 'test', c: true }
7
+ expect(stringifyObject(obj)).toBe('a=1 b=test c=true')
8
+ })
9
+
10
+ it('stringifies a nested object with dot notation', () => {
11
+ const obj = { a: 1, b: { c: 2, d: 'x' } }
12
+ expect(stringifyObject(obj)).toBe('a=1 b.c=2 b.d=x')
13
+ })
14
+
15
+ it('stringifies an object with array values', () => {
16
+ const obj = { a: [1, 2, 3], b: 'x' }
17
+ expect(stringifyObject(obj)).toBe('a=1,2,3 b=x')
18
+ })
19
+
20
+ it('handles objects with undefined and null values', () => {
21
+ const obj = { a: undefined, b: null, c: 1 }
22
+ expect(stringifyObject(obj)).toBe('a=undefined b=null c=1')
23
+ })
24
+
25
+ it('handles deeply nested objects', () => {
26
+ const obj = { a: { b: { c: { d: 1 } } } }
27
+ expect(stringifyObject(obj)).toBe('a.b.c.d=1')
28
+ })
29
+
30
+ it('handles complex nested objects with arrays', () => {
31
+ const obj = {
32
+ config: {
33
+ values: [1, 2],
34
+ settings: { enabled: true },
35
+ },
36
+ name: 'test',
37
+ }
38
+ expect(stringifyObject(obj)).toBe('config.values=1,2 config.settings.enabled=true name=test')
39
+ })
40
+
41
+ it('handles empty object', () => {
42
+ expect(stringifyObject({})).toBe('')
43
+ })
44
+ })
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Stringifies object into the following format:
3
+ *
4
+ * `prop1=value prop2=value prop3.key1=value prop3.key2=value prop4.key1=[value1, value2]`
5
+ *
6
+ * This is useful for logging and debugging.
7
+ */
8
+ export const stringifyObject = (obj: object, prefix = ''): string => {
9
+ const entries: string[] = []
10
+
11
+ for (const [key, value] of Object.entries(obj)) {
12
+ const fullKey = prefix !== '' ? `${prefix}.${key}` : key
13
+
14
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
15
+ // Recursively stringify nested objects with dot notation
16
+ entries.push(stringifyObject(value, fullKey))
17
+ } else if (Array.isArray(value)) {
18
+ // Arrays get converted to comma-separated values
19
+ entries.push(`${fullKey}=${value.join(',')}`)
20
+ } else {
21
+ // Primitive values
22
+ entries.push(`${fullKey}=${value}`)
23
+ }
24
+ }
25
+
26
+ return entries.join(' ')
27
+ }