@livestore/utils 0.0.0-snapshot-909cdd1ac2fd591945c2be2b0f53e14d87f3c9d4

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 (169) hide show
  1. package/dist/.tsbuildinfo.json +1 -0
  2. package/dist/Deferred.d.ts +10 -0
  3. package/dist/Deferred.d.ts.map +1 -0
  4. package/dist/Deferred.js +21 -0
  5. package/dist/Deferred.js.map +1 -0
  6. package/dist/NoopTracer.d.ts +10 -0
  7. package/dist/NoopTracer.d.ts.map +1 -0
  8. package/dist/NoopTracer.js +52 -0
  9. package/dist/NoopTracer.js.map +1 -0
  10. package/dist/base64.d.ts +13 -0
  11. package/dist/base64.d.ts.map +1 -0
  12. package/dist/base64.js +117 -0
  13. package/dist/base64.js.map +1 -0
  14. package/dist/browser.d.ts +3 -0
  15. package/dist/browser.d.ts.map +1 -0
  16. package/dist/browser.js +28 -0
  17. package/dist/browser.js.map +1 -0
  18. package/dist/cuid/cuid.browser.d.ts +18 -0
  19. package/dist/cuid/cuid.browser.d.ts.map +1 -0
  20. package/dist/cuid/cuid.browser.js +80 -0
  21. package/dist/cuid/cuid.browser.js.map +1 -0
  22. package/dist/cuid/cuid.node.d.ts +18 -0
  23. package/dist/cuid/cuid.node.d.ts.map +1 -0
  24. package/dist/cuid/cuid.node.js +83 -0
  25. package/dist/cuid/cuid.node.js.map +1 -0
  26. package/dist/effect/Effect.d.ts +28 -0
  27. package/dist/effect/Effect.d.ts.map +1 -0
  28. package/dist/effect/Effect.js +82 -0
  29. package/dist/effect/Effect.js.map +1 -0
  30. package/dist/effect/Error.d.ts +11 -0
  31. package/dist/effect/Error.d.ts.map +1 -0
  32. package/dist/effect/Error.js +7 -0
  33. package/dist/effect/Error.js.map +1 -0
  34. package/dist/effect/Schedule.d.ts +4 -0
  35. package/dist/effect/Schedule.d.ts.map +1 -0
  36. package/dist/effect/Schedule.js +5 -0
  37. package/dist/effect/Schedule.js.map +1 -0
  38. package/dist/effect/Scheduler.d.ts +4 -0
  39. package/dist/effect/Scheduler.d.ts.map +1 -0
  40. package/dist/effect/Scheduler.js +10 -0
  41. package/dist/effect/Scheduler.js.map +1 -0
  42. package/dist/effect/Schema/debug-diff.d.ts +12 -0
  43. package/dist/effect/Schema/debug-diff.d.ts.map +1 -0
  44. package/dist/effect/Schema/debug-diff.js +51 -0
  45. package/dist/effect/Schema/debug-diff.js.map +1 -0
  46. package/dist/effect/Schema/debug-diff.test.d.ts +2 -0
  47. package/dist/effect/Schema/debug-diff.test.d.ts.map +1 -0
  48. package/dist/effect/Schema/debug-diff.test.js +91 -0
  49. package/dist/effect/Schema/debug-diff.test.js.map +1 -0
  50. package/dist/effect/Schema/index.d.ts +18 -0
  51. package/dist/effect/Schema/index.d.ts.map +1 -0
  52. package/dist/effect/Schema/index.js +29 -0
  53. package/dist/effect/Schema/index.js.map +1 -0
  54. package/dist/effect/Schema/msgpack.d.ts +3 -0
  55. package/dist/effect/Schema/msgpack.d.ts.map +1 -0
  56. package/dist/effect/Schema/msgpack.js +7 -0
  57. package/dist/effect/Schema/msgpack.js.map +1 -0
  58. package/dist/effect/ServiceContext.d.ts +37 -0
  59. package/dist/effect/ServiceContext.d.ts.map +1 -0
  60. package/dist/effect/ServiceContext.js +55 -0
  61. package/dist/effect/ServiceContext.js.map +1 -0
  62. package/dist/effect/Stream.d.ts +10 -0
  63. package/dist/effect/Stream.d.ts.map +1 -0
  64. package/dist/effect/Stream.js +17 -0
  65. package/dist/effect/Stream.js.map +1 -0
  66. package/dist/effect/SubscriptionRef.d.ts +11 -0
  67. package/dist/effect/SubscriptionRef.d.ts.map +1 -0
  68. package/dist/effect/SubscriptionRef.js +5 -0
  69. package/dist/effect/SubscriptionRef.js.map +1 -0
  70. package/dist/effect/WebChannel.d.ts +30 -0
  71. package/dist/effect/WebChannel.d.ts.map +1 -0
  72. package/dist/effect/WebChannel.js +44 -0
  73. package/dist/effect/WebChannel.js.map +1 -0
  74. package/dist/effect/WebLock.d.ts +9 -0
  75. package/dist/effect/WebLock.d.ts.map +1 -0
  76. package/dist/effect/WebLock.js +73 -0
  77. package/dist/effect/WebLock.js.map +1 -0
  78. package/dist/effect/index.d.ts +21 -0
  79. package/dist/effect/index.d.ts.map +1 -0
  80. package/dist/effect/index.js +20 -0
  81. package/dist/effect/index.js.map +1 -0
  82. package/dist/fast-deep-equal.d.ts +2 -0
  83. package/dist/fast-deep-equal.d.ts.map +1 -0
  84. package/dist/fast-deep-equal.js +79 -0
  85. package/dist/fast-deep-equal.js.map +1 -0
  86. package/dist/global.d.ts +5 -0
  87. package/dist/global.d.ts.map +1 -0
  88. package/dist/global.js +2 -0
  89. package/dist/global.js.map +1 -0
  90. package/dist/guards.d.ts +6 -0
  91. package/dist/guards.d.ts.map +1 -0
  92. package/dist/guards.js +6 -0
  93. package/dist/guards.js.map +1 -0
  94. package/dist/index.d.ts +76 -0
  95. package/dist/index.d.ts.map +1 -0
  96. package/dist/index.js +176 -0
  97. package/dist/index.js.map +1 -0
  98. package/dist/misc.d.ts +3 -0
  99. package/dist/misc.d.ts.map +1 -0
  100. package/dist/misc.js +24 -0
  101. package/dist/misc.js.map +1 -0
  102. package/dist/nanoid/index.d.ts +2 -0
  103. package/dist/nanoid/index.d.ts.map +1 -0
  104. package/dist/nanoid/index.js +2 -0
  105. package/dist/nanoid/index.js.map +1 -0
  106. package/dist/object/index.d.ts +10 -0
  107. package/dist/object/index.d.ts.map +1 -0
  108. package/dist/object/index.js +10 -0
  109. package/dist/object/index.js.map +1 -0
  110. package/dist/object/omit.d.ts +3 -0
  111. package/dist/object/omit.d.ts.map +1 -0
  112. package/dist/object/omit.js +14 -0
  113. package/dist/object/omit.js.map +1 -0
  114. package/dist/object/pick.d.ts +14 -0
  115. package/dist/object/pick.d.ts.map +1 -0
  116. package/dist/object/pick.js +17 -0
  117. package/dist/object/pick.js.map +1 -0
  118. package/dist/promise.d.ts +6 -0
  119. package/dist/promise.d.ts.map +1 -0
  120. package/dist/promise.js +27 -0
  121. package/dist/promise.js.map +1 -0
  122. package/dist/set.d.ts +2 -0
  123. package/dist/set.d.ts.map +1 -0
  124. package/dist/set.js +10 -0
  125. package/dist/set.js.map +1 -0
  126. package/dist/string.d.ts +5 -0
  127. package/dist/string.d.ts.map +1 -0
  128. package/dist/string.js +8 -0
  129. package/dist/string.js.map +1 -0
  130. package/dist/time.d.ts +12 -0
  131. package/dist/time.d.ts.map +1 -0
  132. package/dist/time.js +22 -0
  133. package/dist/time.js.map +1 -0
  134. package/package.json +74 -0
  135. package/src/Deferred.ts +24 -0
  136. package/src/NoopTracer.ts +75 -0
  137. package/src/ambient.d.ts +3 -0
  138. package/src/base64.ts +123 -0
  139. package/src/browser.ts +32 -0
  140. package/src/cuid/cuid.browser.ts +95 -0
  141. package/src/cuid/cuid.node.ts +103 -0
  142. package/src/effect/Effect.ts +180 -0
  143. package/src/effect/Error.ts +6 -0
  144. package/src/effect/Schedule.ts +10 -0
  145. package/src/effect/Scheduler.ts +14 -0
  146. package/src/effect/Schema/debug-diff.test.ts +102 -0
  147. package/src/effect/Schema/debug-diff.ts +58 -0
  148. package/src/effect/Schema/index.ts +58 -0
  149. package/src/effect/Schema/msgpack.ts +8 -0
  150. package/src/effect/ServiceContext.ts +108 -0
  151. package/src/effect/Stream.ts +63 -0
  152. package/src/effect/SubscriptionRef.ts +22 -0
  153. package/src/effect/WebChannel.ts +116 -0
  154. package/src/effect/WebLock.ts +95 -0
  155. package/src/effect/index.ts +91 -0
  156. package/src/fast-deep-equal.ts +72 -0
  157. package/src/global.ts +5 -0
  158. package/src/guards.ts +8 -0
  159. package/src/index.ts +240 -0
  160. package/src/misc.ts +26 -0
  161. package/src/nanoid/index.ts +1 -0
  162. package/src/object/index.ts +24 -0
  163. package/src/object/omit.ts +17 -0
  164. package/src/object/pick.ts +27 -0
  165. package/src/promise.ts +43 -0
  166. package/src/set.ts +10 -0
  167. package/src/string.ts +9 -0
  168. package/src/time.ts +25 -0
  169. package/tsconfig.json +10 -0
package/src/index.ts ADDED
@@ -0,0 +1,240 @@
1
+ export * from './string.js'
2
+ export * from './guards.js'
3
+ export * from './object/index.js'
4
+ export * from './promise.js'
5
+ export * from './time.js'
6
+ export * from './NoopTracer.js'
7
+ export * from './set.js'
8
+ export * from './browser.js'
9
+ export * from './Deferred.js'
10
+ export * from './misc.js'
11
+ export * from './fast-deep-equal.js'
12
+ export * as base64 from './base64.js'
13
+ export { default as prettyBytes } from 'pretty-bytes'
14
+
15
+ import type * as otel from '@opentelemetry/api'
16
+
17
+ import { objectToString } from './misc.js'
18
+
19
+ export type Prettify<T> = T extends infer U ? { [K in keyof U]: Prettify<U[K]> } : never
20
+ export type PrettifyFlat<T> = T extends infer U ? { [K in keyof U]: U[K] } : never
21
+
22
+ export type TypeEq<A, B> = (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2 ? true : false
23
+
24
+ /** `A` is subtype of `B` */
25
+ export type IsSubtype<A, B> = A extends B ? true : false
26
+ export type AssertTrue<T extends true> = T
27
+
28
+ export type Writeable<T> = { -readonly [P in keyof T]: T[P] }
29
+ export type DeepWriteable<T> = { -readonly [P in keyof T]: DeepWriteable<T[P]> }
30
+
31
+ export type Primitive = null | undefined | string | number | boolean | symbol | bigint
32
+
33
+ export type LiteralUnion<LiteralType, BaseType extends Primitive> = LiteralType | (BaseType & Record<never, never>)
34
+
35
+ export type GetValForKey<T, K> = K extends keyof T ? T[K] : never
36
+
37
+ export const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))
38
+
39
+ export const ref = <T>(val: T): { current: T } => ({ current: val })
40
+
41
+ export const times = (n: number, fn: (index: number) => {}): void => {
42
+ for (let i = 0; i < n; i++) {
43
+ fn(i)
44
+ }
45
+ }
46
+
47
+ export const debugCatch = <T>(try_: () => T): T => {
48
+ try {
49
+ return try_()
50
+ } catch (e: any) {
51
+ debugger
52
+ throw e
53
+ }
54
+ }
55
+
56
+ export const recRemoveUndefinedValues = (val: any): void => {
57
+ if (Array.isArray(val)) {
58
+ val.forEach(recRemoveUndefinedValues)
59
+ } else if (typeof val === 'object') {
60
+ Object.keys(val).forEach((key) => {
61
+ if (val[key] === undefined) {
62
+ delete val[key]
63
+ } else {
64
+ recRemoveUndefinedValues(val[key])
65
+ }
66
+ })
67
+ }
68
+ }
69
+
70
+ export const prop =
71
+ <T extends {}, K extends keyof T>(key: K) =>
72
+ (obj: T): T[K] =>
73
+ obj[key]
74
+
75
+ export const capitalizeFirstLetter = (str: string): string => str.charAt(0).toUpperCase() + str.slice(1)
76
+
77
+ export const isReadonlyArray = <I, T>(value: ReadonlyArray<I> | T): value is ReadonlyArray<I> => Array.isArray(value)
78
+
79
+ /**
80
+ * Use this to make assertion at end of if-else chain that all members of a
81
+ * union have been accounted for.
82
+ */
83
+ /* eslint-disable-next-line prefer-arrow/prefer-arrow-functions */
84
+ export function casesHandled(unexpectedCase: never): never {
85
+ debugger
86
+ throw new Error(`A case was not handled for value: ${truncate(objectToString(unexpectedCase), 1000)}`)
87
+ }
88
+
89
+ export const shouldNeverHappen = (msg?: string, ...args: any[]): never => {
90
+ console.error(msg, ...args)
91
+ if (isDev()) {
92
+ debugger
93
+ }
94
+
95
+ throw new Error(`This should never happen: ${msg}`)
96
+ }
97
+
98
+ export const assertNever = (failIfFalse: boolean, msg?: string): void => {
99
+ if (failIfFalse === false) {
100
+ debugger
101
+ throw new Error(`This should never happen: ${msg}`)
102
+ }
103
+ }
104
+
105
+ export const debuggerPipe = <T>(val: T): T => {
106
+ debugger
107
+ return val
108
+ }
109
+
110
+ const truncate = (str: string, length: number): string => {
111
+ if (str.length > length) {
112
+ return str.slice(0, length) + '...'
113
+ } else {
114
+ return str
115
+ }
116
+ }
117
+
118
+ export const notYetImplemented = (msg?: string): never => {
119
+ debugger
120
+ throw new Error(`Not yet implemented: ${msg}`)
121
+ }
122
+
123
+ export const noop = () => {}
124
+
125
+ export type Thunk<T> = () => T
126
+
127
+ export const unwrapThunk = <T>(_: T | (() => T)): T => {
128
+ if (typeof _ === 'function') {
129
+ return (_ as any)()
130
+ } else {
131
+ return _
132
+ }
133
+ }
134
+
135
+ export type NullableFieldsToOptional<T> = PrettifyFlat<
136
+ Partial<T> & {
137
+ [K in keyof T as null extends T[K] ? K : never]?: Exclude<T[K], null>
138
+ } & {
139
+ [K in keyof T as null extends T[K] ? never : K]: T[K]
140
+ }
141
+ >
142
+
143
+ /** `end` is not included */
144
+ export const range = (start: number, end: number): number[] => {
145
+ const length = end - start
146
+ return Array.from({ length }, (_, i) => start + i)
147
+ }
148
+
149
+ export const throttle = (fn: () => void, ms: number) => {
150
+ let shouldWait = false
151
+ let shouldCallAgain = false
152
+
153
+ const timeoutFunc = () => {
154
+ if (shouldCallAgain) {
155
+ fn()
156
+ shouldCallAgain = false
157
+ setTimeout(timeoutFunc, ms)
158
+ } else {
159
+ shouldWait = false
160
+ }
161
+ }
162
+
163
+ return () => {
164
+ if (shouldWait) {
165
+ shouldCallAgain = true
166
+ return
167
+ }
168
+
169
+ fn()
170
+ shouldWait = true
171
+ setTimeout(timeoutFunc, ms)
172
+ }
173
+ }
174
+
175
+ export const getTraceParentHeader = (parentSpan: otel.Span) => {
176
+ const spanContext = parentSpan.spanContext()
177
+ // Format: {version}-{trace_id}-{span_id}-{trace_flags}
178
+ // https://www.w3.org/TR/trace-context/#examples-of-http-traceparent-headers
179
+ return `00-${spanContext.traceId}-${spanContext.spanId}-01`
180
+ }
181
+
182
+ export const assertTag = <TObj extends { _tag: string }, TTag extends TObj['_tag']>(
183
+ obj: TObj,
184
+ tag: TTag,
185
+ ): Extract<TObj, { _tag: TTag }> => {
186
+ if (obj._tag !== tag) {
187
+ throw new Error(`Expected tag ${tag} but got ${obj._tag}`)
188
+ }
189
+
190
+ return obj as any
191
+ }
192
+
193
+ export const memoizeByStringifyArgs = <T extends (...args: any[]) => any>(fn: T): T => {
194
+ const cache = new Map<string, ReturnType<T>>()
195
+
196
+ return ((...args: any[]) => {
197
+ const key = JSON.stringify(args)
198
+ if (cache.has(key)) {
199
+ return cache.get(key)
200
+ }
201
+
202
+ const result = fn(...args)
203
+ cache.set(key, result)
204
+ return result
205
+ }) as any
206
+ }
207
+
208
+ export const memoizeByRef = <T extends (arg: any) => any>(fn: T): T => {
209
+ const cache = new Map<Parameters<T>[0], ReturnType<T>>()
210
+
211
+ return ((arg: any) => {
212
+ if (cache.has(arg)) {
213
+ return cache.get(arg)
214
+ }
215
+
216
+ const result = fn(arg)
217
+ cache.set(arg, result)
218
+ return result
219
+ }) as any
220
+ }
221
+
222
+ export const isNonEmptyString = (str: string | undefined | null): str is string => {
223
+ return typeof str === 'string' && str.length > 0
224
+ }
225
+
226
+ export const isPromise = (value: any): value is Promise<unknown> => typeof value?.then === 'function'
227
+
228
+ export const isIterable = <T>(value: any): value is Iterable<T> => typeof value?.[Symbol.iterator] === 'function'
229
+
230
+ export { objectToString as errorToString } from './misc.js'
231
+
232
+ const isDev = memoizeByRef(() => {
233
+ if (import.meta.env !== undefined) {
234
+ return import.meta.env.DEV || import.meta.env.VITE_DEV
235
+ } else if (typeof process !== 'undefined' && process.env !== undefined) {
236
+ return process.env.DEV
237
+ } else {
238
+ return false
239
+ }
240
+ })
package/src/misc.ts ADDED
@@ -0,0 +1,26 @@
1
+ export const objectToString = (error: any): string => {
2
+ const str = error?.toString()
3
+ if (str !== '[object Object]') return str
4
+
5
+ try {
6
+ return JSON.stringify(error, null, 2)
7
+ } catch (e: any) {
8
+ console.log(error)
9
+
10
+ return 'Error while printing error: ' + e
11
+ }
12
+ }
13
+
14
+ export const tryAsFunctionAndNew = <TArg, TResult>(
15
+ fnOrConstructor: ((arg: TArg) => TResult) | (new (arg: TArg) => TResult),
16
+ arg: TArg,
17
+ ): TResult => {
18
+ try {
19
+ // @ts-expect-error try out as constructor
20
+ return new fnOrConstructor(arg)
21
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
22
+ } catch (e) {
23
+ // @ts-expect-error try out as function
24
+ return fnOrConstructor(arg)
25
+ }
26
+ }
@@ -0,0 +1 @@
1
+ export { nanoid } from 'nanoid'
@@ -0,0 +1,24 @@
1
+ import { pipe } from 'effect'
2
+
3
+ export * from './pick.js'
4
+ export * from './omit.js'
5
+
6
+ type ValueOfRecord<R extends Record<any, any>> = R extends Record<any, infer V> ? V : never
7
+
8
+ export const mapObjectValues = <O_In extends Record<string, any>, V_Out>(
9
+ obj: O_In,
10
+ mapValue: (key: keyof O_In, val: ValueOfRecord<O_In>) => V_Out,
11
+ ): { [K in keyof O_In]: V_Out } => {
12
+ const mappedEntries = Object.entries(obj).map(([key, val]) => [key, mapValue(key as keyof O_In, val)] as const)
13
+ return Object.fromEntries(mappedEntries) as any
14
+ }
15
+
16
+ export type Entries<T> = { [K in keyof T]: [K, T[K]] }[keyof T][]
17
+
18
+ export const objectEntries = <T extends Record<string, any>>(obj: T): Entries<T> => Object.entries(obj) as Entries<T>
19
+
20
+ export const keyObjectFromObject = <TObj extends Record<string, any>>(obj: TObj): { [K in keyof TObj]: K } =>
21
+ pipe(
22
+ objectEntries(obj).map(([k]) => [k, k]),
23
+ Object.fromEntries,
24
+ ) as any
@@ -0,0 +1,17 @@
1
+ // type ConvertUndefined<T> = OrUndefined<{ [K in keyof T as undefined extends T[K] ? K : never]-?: T[K] }>
2
+ // type OrUndefined<T> = { [K in keyof T]: T[K] | undefined }
3
+ // type PickRequired<T> = { [K in keyof T as undefined extends T[K] ? never : K]: T[K] }
4
+ // type ConvertPick<T> = ConvertUndefined<T> & PickRequired<T>
5
+
6
+ /** Returns a shallowly cloned object with the provided keys omitted */
7
+ export const omit = <Obj extends Record<string, any>, Keys extends keyof Obj>(
8
+ obj: Obj,
9
+ keys: Keys[],
10
+ ): Omit<Obj, Keys> => {
11
+ return Object.keys(obj).reduce((acc, key: any) => {
12
+ if (!keys.includes(key)) {
13
+ acc[key] = (obj as any)[key]
14
+ }
15
+ return acc
16
+ }, {} as any)
17
+ }
@@ -0,0 +1,27 @@
1
+ type ConvertUndefined<T> = OrUndefined<{ [K in keyof T as undefined extends T[K] ? K : never]-?: T[K] }>
2
+ type OrUndefined<T> = { [K in keyof T]: T[K] | undefined }
3
+ type PickRequired<T> = { [K in keyof T as undefined extends T[K] ? never : K]: T[K] }
4
+ type ConvertPick<T> = ConvertUndefined<T> & PickRequired<T>
5
+
6
+ export const pick = <Obj, Keys extends keyof Obj>(obj: Obj, keys: Keys[]): ConvertPick<{ [K in Keys]: Obj[K] }> => {
7
+ return keys.reduce((acc, key) => {
8
+ acc[key] = obj[key]
9
+ return acc
10
+ }, {} as any)
11
+ }
12
+
13
+ export const pickAllOrElse = <Obj, Keys extends keyof Obj, TElse>(
14
+ obj: Obj,
15
+ keys: Keys[],
16
+ elseValue: TElse,
17
+ ): ConvertPick<{ [K in Keys]: NonNullable<Obj[K]> }> | TElse => {
18
+ const ret = {} as any
19
+ for (const key of keys) {
20
+ if (obj[key] === undefined) {
21
+ return elseValue
22
+ }
23
+ ret[key] = obj[key]
24
+ }
25
+
26
+ return ret
27
+ }
package/src/promise.ts ADDED
@@ -0,0 +1,43 @@
1
+ /** Promise.all + Array.map */
2
+ export const promiseMap = <T, Res>(arr: T[], map: (el: T, index?: number) => Res | Promise<Res>) =>
3
+ Promise.all(arr.map(map))
4
+
5
+ export const promiseMapDict = async <T, Res>(
6
+ dict: Record<string, T>,
7
+ map: (el: T, index?: number) => Res | Promise<Res>,
8
+ ): Promise<Record<string, Res>> => {
9
+ const mappedEntries = await Promise.all(Object.entries(dict).map(async ([key, val]) => [key, await map(val)]))
10
+ return Object.fromEntries(mappedEntries)
11
+ }
12
+
13
+ export const promiseMapToDict = async <T, Res>(
14
+ arr: T[],
15
+ mapValue: (el: T, index?: number) => Res | Promise<Res>,
16
+ mapKey: (el: T, index?: number) => string,
17
+ ): Promise<Record<string, Res>> => {
18
+ const mappedEntries = await Promise.all(arr.map(async (el, index) => [mapKey(el, index), await mapValue(el, index)]))
19
+
20
+ return Object.fromEntries(mappedEntries)
21
+ }
22
+
23
+ export const promiseMapPool = async <T, Res>(
24
+ arr: T[],
25
+ map: (el: T, index?: number) => Promise<Res>,
26
+ poolLimit: number,
27
+ ): Promise<Res[]> => {
28
+ const ret: Promise<Res>[] = []
29
+ const executing: Promise<Res>[] = []
30
+ for (const [index, item] of arr.entries()) {
31
+ const p = Promise.resolve().then(() => map(item, index))
32
+ ret.push(p)
33
+
34
+ if (poolLimit <= arr.length) {
35
+ const e: any = p.then(() => executing.splice(executing.indexOf(e), 1))
36
+ executing.push(e)
37
+ if (executing.length >= poolLimit) {
38
+ await Promise.race(executing)
39
+ }
40
+ }
41
+ }
42
+ return Promise.all(ret)
43
+ }
package/src/set.ts ADDED
@@ -0,0 +1,10 @@
1
+ export const difference = <T>(a: Set<T>, b: Set<T>) => {
2
+ const diff = new Set<T>()
3
+ for (const item of a) {
4
+ if (!b.has(item)) {
5
+ diff.add(item)
6
+ }
7
+ }
8
+
9
+ return diff
10
+ }
package/src/string.ts ADDED
@@ -0,0 +1,9 @@
1
+ export const lowercaseFirstChar = (str: string) => str.charAt(0).toLowerCase() + str.slice(1)
2
+ export const uppercaseFirstChar = (str: string) => str.charAt(0).toUpperCase() + str.slice(1)
3
+
4
+ /** Indents a string each line by `n` characters (default: spaces) */
5
+ export const indent = (str: string, n: number, char = ' '): string =>
6
+ str
7
+ .split('\n')
8
+ .map((line) => char.repeat(n) + line)
9
+ .join('\n')
package/src/time.ts ADDED
@@ -0,0 +1,25 @@
1
+ export const minuteInMs = 1000 * 60
2
+
3
+ export const time = {
4
+ ms: 1,
5
+ sec: 1000,
6
+ min: 60 * 1000,
7
+ hour: 60 * 60 * 1000,
8
+ day: 24 * 60 * 60 * 1000,
9
+ week: 7 * 24 * 60 * 60 * 1000,
10
+ }
11
+
12
+ /** Returns a string of format `m:ss` / `mm:ss` / `h:mm:ss` / ... */
13
+ export const msAsTimeString = (ms: number) => {
14
+ const seconds = Math.floor(ms / 1000)
15
+ const minutes = Math.floor(seconds / 60)
16
+ const hours = Math.floor(minutes / 60)
17
+ const remainingSeconds = (seconds % 60).toString().padStart(2, '0')
18
+ const remainingMinutes = hours > 0 ? (minutes % 60).toString().padStart(2, '0') : minutes % 60
19
+
20
+ const timeString = [hours > 0 ? `${hours}:` : '', `${remainingMinutes}:`, `${remainingSeconds}`]
21
+ .filter((val) => val !== '')
22
+ .join('')
23
+
24
+ return timeString
25
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "rootDir": "./src",
5
+ "outDir": "./dist",
6
+ "tsBuildInfoFile": "./dist/.tsbuildinfo.json"
7
+ },
8
+ "include": ["./src"],
9
+ "references": [{ "path": "../db-schema"}]
10
+ }