@rhombus-toolkit/obj 0.0.0-placeholder.0 → 1.0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 rhombus-toolkit
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,262 @@
1
+ import { Store, Flatten, UnionToTuple, DeepDictionary, Func, Falsy, Cast } from '@rhombus-toolkit/types';
2
+
3
+ type Entry<Key extends PropertyKey = PropertyKey, Value = any> = readonly [Key, Value];
4
+ /** The keys `Object.keys` lists — string-named, so a symbol-named member never appears. */
5
+ type StringKey<T> = Extract<keyof T, string>;
6
+ /** A key the runtime hoists ahead of the others and lists in ascending numeric order. */
7
+ type IndexKey<T> = Extract<keyof T, number | `${number}`>;
8
+ /** A member declared with `?`, which the object at hand may or may not carry. */
9
+ type OptionalKey<T> = {
10
+ [K in keyof T]-?: {} extends Pick<T, K> ? K : never;
11
+ }[keyof T];
12
+ /**
13
+ * Every reason `T`'s keys cannot be spelled as a tuple.
14
+ *
15
+ * @remarks
16
+ * Where this is inhabited, {@link keys} and {@link entries} keep only their array arm. Each member
17
+ * disqualifies for its own reason: an {@link IndexKey} is listed first and numerically rather than
18
+ * in the order the type holds it, and sorting it into place is not something the type system does
19
+ * cheaply; an {@link OptionalKey} may be absent at the call, so neither the length nor any position
20
+ * after it is fixed; and a `string` index signature admits any number of keys, which would otherwise
21
+ * be tupled as the single key `string`.
22
+ *
23
+ * `${number}` also matches spellings that are not array indices — `'1.5'`, `'-3'` — costing an
24
+ * object keyed that way its tuple and nothing else.
25
+ */
26
+ type Untuplable<T> = IndexKey<T> | OptionalKey<T> | (string extends StringKey<T> ? string : never);
27
+ type keyTuple<T extends {}> = UnionToTuple<StringKey<T>>;
28
+ /**
29
+ * The string keys `Object.keys` yields.
30
+ *
31
+ * @remarks
32
+ * The tuple arm carries the order and is withheld whenever {@link Untuplable} finds a reason to
33
+ * doubt it. The array arm is unconditional, so `map` and the rest stay reachable while `T` is still
34
+ * a type parameter — a position where neither the tuple nor the test in front of it can be
35
+ * evaluated, and an unevaluated conditional carries no members at all.
36
+ */
37
+ type keys<T extends {}> = ([Untuplable<T>] extends [never] ? keyTuple<T> : unknown) & ReadonlyArray<StringKey<T>>;
38
+ declare function keys<T extends {}>(obj: T): keys<T>;
39
+ /** The members `Object.values` yields, symbol-named ones excluded as the runtime excludes them. */
40
+ type values<T extends {}> = T[StringKey<T>];
41
+ declare function values<T extends {}>(obj: T): Array<values<T>>;
42
+ /** Every pair `T` can yield, each key carrying its own member type rather than the union of all. */
43
+ type AnyEntry<T extends {}> = {
44
+ [K in StringKey<T>]: Entry<K, T[K]>;
45
+ }[StringKey<T>];
46
+ /**
47
+ * The `[key, value]` pairs `Object.entries` yields, in the order {@link keys} lists them.
48
+ *
49
+ * @remarks
50
+ * Withholds its tuple arm on the same condition as {@link keys}, and keeps its array arm for the
51
+ * same reason.
52
+ */
53
+ type entries<T extends {}> = ([Untuplable<T>] extends [never] ? keysToEntries<T, keyTuple<T>> : unknown) & ReadonlyArray<AnyEntry<T>>;
54
+ declare function entries<T extends {}>(obj: T): entries<T>;
55
+ /**
56
+ * `Keys` paired with the member each one names on `T`.
57
+ *
58
+ * @remarks
59
+ * The key tuple arrives as a parameter rather than being computed inline so the mapped type reads it
60
+ * as a tuple and hands back a tuple; mapping straight over an unevaluated conditional maps something
61
+ * that contributes `length` and the array methods as members of its own.
62
+ */
63
+ type keysToEntries<T extends {}, Keys extends ReadonlyArray<StringKey<T>>> = {
64
+ [K in keyof Keys]: Entry<Keys[K], T[Keys[K]]>;
65
+ };
66
+ type fromEntries<TUnion extends Entry> = {
67
+ [T in TUnion as T[0]]: T[1];
68
+ };
69
+ declare function fromEntries<TEntry extends Entry>(entries: readonly TEntry[]): fromEntries<TEntry>;
70
+ type _assign<Sources extends readonly any[], Result extends {}> = Sources extends readonly [...infer Rest, infer Last] ? _assign<Rest, ShallowMerge<Last, Result>> : Result;
71
+ /**
72
+ * The result of `Object.assign(target, ...sources)`: each source shallow-merged over the one before
73
+ * it, left to right.
74
+ *
75
+ * @remarks
76
+ * Arrays and objects merge differently, so {@link ShallowMerge} dispatches on the pair. Two arrays
77
+ * merge INDEX-WISE and the result is as long as the longer of them, which is what makes a short
78
+ * overlay leave the tail alone. Anything else merges by key.
79
+ */
80
+ type assign<Sources extends readonly any[]> = _assign<Sources, Sources[0] extends readonly any[] ? [] : {}>;
81
+ declare function assign<Target extends object, Sources extends any[]>(target: Target, ...sources: Sources): assign<[Target, ...Sources]>;
82
+ type ShallowMerge<A, B> = A extends readonly any[] ? B extends readonly any[] ? MergeArrays<A, B> : MergeObjects<A, B> : MergeObjects<A, B>;
83
+ /**
84
+ * `B` overlaid on `A` index-wise, walking one position at a time and stopping once both are spent.
85
+ * The result is as long as the longer of the two, which is what leaves a short overlay's tail alone.
86
+ *
87
+ * @remarks
88
+ * The walk's budget is a tuple peeled one cell per step rather than a number run down through
89
+ * `Dec`. `Dec<N>` is `Length<Tail<Counter<N>>>` and `Counter` recurses without a bound while its
90
+ * argument is still a parameter, so relating `Dec<TTL>` back to a `TTL extends number` constraint
91
+ * fails at this declaration with "Excessive stack depth" — the same reason `counter`'s own
92
+ * `Subtract` peels tuples instead of routing through `Skip`. It only compiled before because the
93
+ * `Dec` in scope was a generated lookup table, which this package's move onto
94
+ * `@rhombus-toolkit/types` retires.
95
+ */
96
+ type MergeArrays<A extends readonly any[], B extends readonly any[]> = _MergeArrays<Store<15>, A, B, [], []>;
97
+ type _MergeArrays<TTL extends readonly any[], A extends readonly any[], B extends readonly any[], I extends readonly any[], Acc extends readonly any[]> = TTL extends readonly [any, ...infer TTLRest] ? Spent<A, B, I> extends true ? Acc : _MergeArrays<TTLRest, A, B, [...I, any], [...Acc, MergeValue<A, B, I['length']>]> : never;
98
+ /**
99
+ * `B`'s element at this index, falling back to `A`'s where `B` has none.
100
+ *
101
+ * @remarks
102
+ * `undefined` counts as "none". A tuple type cannot tell a hole (`[, 7]`) from an explicit
103
+ * `undefined` — both read as `undefined` — so falling back is the only reading available, and it is
104
+ * the one a sparse overlay wants. It does diverge from the runtime, where an explicit `undefined`
105
+ * overwrites.
106
+ */
107
+ type MergeValue<A extends readonly any[], B extends readonly any[], N extends number> = At<B, N> extends undefined ? At<A, N> : At<B, N>;
108
+ type MergeObjects<A, B> = Flatten<Omit<A, keyof B> & B>;
109
+ /** `T`'s element at `N`, or `undefined` where `T` is too short to have one. */
110
+ type At<T extends readonly any[], N extends number> = N extends keyof T ? T[N] : undefined;
111
+ /** Whether the walk has reached the end of both `A` and `B`. */
112
+ type Spent<A extends readonly any[], B extends readonly any[], I extends readonly any[]> = Covers<A, I> extends true ? Covers<B, I> extends true ? true : false : false;
113
+ /**
114
+ * Whether `I` has walked past everything `T` can offer.
115
+ *
116
+ * @remarks
117
+ * A length of `number` rather than a literal means an unbounded array, or a type parameter still
118
+ * standing in for one. There is no index to walk to, so such an operand is covered from the start
119
+ * and contributes nothing. Without that, a merge inside a generic function has no base case and
120
+ * the checker gives up with an excessive-stack-depth error.
121
+ */
122
+ type Covers<T extends readonly any[], I extends readonly any[]> = number extends T['length'] ? true : keyof T extends keyof I ? true : false;
123
+
124
+ type obj_AnyEntry<T extends {}> = AnyEntry<T>;
125
+ type obj_Entry<Key extends PropertyKey = PropertyKey, Value = any> = Entry<Key, Value>;
126
+ declare const obj_assign: typeof assign;
127
+ declare const obj_entries: typeof entries;
128
+ declare const obj_fromEntries: typeof fromEntries;
129
+ declare const obj_keys: typeof keys;
130
+ type obj_keysToEntries<T extends {}, Keys extends ReadonlyArray<StringKey<T>>> = keysToEntries<T, Keys>;
131
+ declare const obj_values: typeof values;
132
+ declare namespace obj {
133
+ export { obj_assign as assign, obj_entries as entries, obj_fromEntries as fromEntries, obj_keys as keys, obj_values as values };
134
+ export type { obj_AnyEntry as AnyEntry, obj_Entry as Entry, obj_keysToEntries as keysToEntries };
135
+ }
136
+
137
+ declare function join<S1 extends string, S2 extends string>(a: S1, b: S2): join<S1, S2>;
138
+ /**
139
+ * `A` and `B` dot-joined, either one being empty giving the other back on its own.
140
+ *
141
+ * @remarks
142
+ * Every arm is `string`-shaped, `Cast<B, string>` included: a `B` of `symbol` or `number` has no
143
+ * literal spelling, so it widens to `string` rather than escaping as a non-string key. Without that
144
+ * the empty-`A` arm handed a bare `PropertyKey` to `_flattenMap`'s `prefix extends string`.
145
+ */
146
+ type join<A extends string, B extends PropertyKey> = A extends Falsy ? Cast<B, string> : B extends Falsy ? A : `${A}.${Cast<B, string>}`;
147
+ /**
148
+ * The descent, `Budget` spending one cell per level.
149
+ *
150
+ * @remarks
151
+ * A tuple rather than a number run down through `Dec`: `Dec<N>` is `Length<Tail<Counter<N>>>`, and
152
+ * relating that back to a `number`-constrained parameter drags `Counter`'s unbounded recursion into
153
+ * the comparison, which fails at this declaration with "Excessive stack depth". `Store<MaxDepth>`
154
+ * does the number-to-tuple conversion once, at the public entry, so the depth stays a plain number
155
+ * for a caller.
156
+ */
157
+ type _flattenMap<T extends DeepDictionary<any>, Leaf, prefix extends string, Budget extends readonly any[]> = Budget extends readonly [any, ...infer Rest] ? T extends Leaf ? [prefix, T] : T extends Record<any, any> ? {
158
+ [K in keyof T]: _flattenMap<T[K], Leaf, join<prefix, K>, Rest>;
159
+ }[keyof T] : never : never;
160
+ /**
161
+ * `T`'s leaves keyed by the dot-joined path each one sits at.
162
+ *
163
+ * @remarks
164
+ * Both defaults exist to keep the one-argument `flattenMap<M>` of the version
165
+ * this replaces spelling the same type. That version hardcoded its leaf as
166
+ * {@link Func} and guarded at a depth of 10, so a `TLeaf` of anything else or a
167
+ * `MaxDepth` below 10 would quietly turn a map that used to flatten into
168
+ * `never`.
169
+ */
170
+ type flattenMap<T extends DeepDictionary<any>, TLeaf = Func, MaxDepth extends number = 10> = fromEntries<_flattenMap<T, TLeaf, '', Store<MaxDepth>>>;
171
+ /** Flattens `map` with `isFunction` as the leaf test — the shape the superseded version had. */
172
+ declare function flattenMap<T extends DeepDictionary<Func>>(map: T): flattenMap<T>;
173
+ /**
174
+ * Flattens `map`, `leafPredicate` deciding what counts as a leaf.
175
+ *
176
+ * The predicate is spelled out rather than reached for as a `Func`: a type
177
+ * guard's return is a type predicate, which `Func`'s `Return` parameter has no
178
+ * way to carry.
179
+ */
180
+ declare function flattenMap<T extends DeepDictionary<Leaf>, Leaf>(map: T, leafPredicate: (p: any) => p is Leaf): flattenMap<T, Leaf>;
181
+
182
+ /** Yields every element of `source`, substituting `replacement` for each one `match` selects — an exact value or a predicate. */
183
+ declare function replace<T>(source: Iterable<T>, match: T | Func<[T], boolean>, replacement: Func<[T], T>): Generator<T>;
184
+ declare function replace<T, U>(source: Iterable<T>, match: T | Func<[T], boolean>, replacement: Func<[T], U>): Generator<T | U>;
185
+ declare function replace<T>(source: Iterable<T>, match: T | Func<[T], boolean>, replacement: T): Generator<T>;
186
+ declare function replace<T, U>(source: Iterable<T>, match: T | Func<[T], boolean>, replacement: U): Generator<T | U>;
187
+ /** The first element `source` yields, or `undefined` when it yields nothing. */
188
+ declare function first<T>(source: Iterable<T>): T | undefined;
189
+ /**
190
+ * Type guard: whether every element of `items` is present — none are `undefined`.
191
+ *
192
+ * @remarks
193
+ * Deciding this reads `items` to the end, so a one-shot source is spent by the call and the
194
+ * narrowed value it hands back yields nothing. Pass an array, a `Set`, or anything else that can
195
+ * be iterated twice.
196
+ */
197
+ declare function isAllThere<T>(items: ReadonlyArray<T | undefined>): items is readonly T[];
198
+ declare function isAllThere<T>(items: Iterable<T | undefined>): items is Iterable<T>;
199
+ /**
200
+ * Yields each argument's elements in order, an argument that is not iterable yielded as itself.
201
+ *
202
+ * @remarks
203
+ * `Iterable<T> | T` is genuinely ambiguous once `T` is itself iterable, and `isIterable` is the
204
+ * only arbiter at runtime: a `T` of `string` arrives flattened into its characters, since a string
205
+ * carries `Symbol.iterator`. The `Iterator.from` on the iterable arm is what makes that hold rather
206
+ * than throw — `flatMap` rejects a primitive outright, where `Iterator.from` iterates a string.
207
+ */
208
+ declare function concat<T>(...args: ReadonlyArray<Iterable<T> | T>): IteratorObject<T, undefined, unknown>;
209
+ /** Wraps an iterator factory as an `Iterable`, so every walk over the result asks `fn` for a fresh iterator. */
210
+ declare function iterable<T>(fn: Func<[], Iterator<T>>): Iterable<T>;
211
+ /**
212
+ * Yields tuples pairing the sources' elements positionally. `inner` ends with the shortest source,
213
+ * every slot present; `outer` runs to the longest, an exhausted source's slot `undefined` — which a
214
+ * source yielding `undefined` is indistinguishable from.
215
+ */
216
+ declare function zip<T1, T2>(mode: 'inner', source1: Iterable<T1>, source2: Iterable<T2>): Generator<[T1, T2]>;
217
+ declare function zip<T1, T2, T3>(mode: 'inner', source1: Iterable<T1>, source2: Iterable<T2>, source3: Iterable<T3>): Generator<[T1, T2, T3]>;
218
+ declare function zip<T1, T2, T3, T4>(mode: 'inner', source1: Iterable<T1>, source2: Iterable<T2>, source3: Iterable<T3>, source4: Iterable<T4>): Generator<[T1, T2, T3, T4]>;
219
+ declare function zip<T1, T2, T3, T4, T5>(mode: 'inner', source1: Iterable<T1>, source2: Iterable<T2>, source3: Iterable<T3>, source4: Iterable<T4>, source5: Iterable<T5>): Generator<[T1, T2, T3, T4, T5]>;
220
+ declare function zip<T1, T2, T3, T4, T5, T6>(mode: 'inner', source1: Iterable<T1>, source2: Iterable<T2>, source3: Iterable<T3>, source4: Iterable<T4>, source5: Iterable<T5>, source6: Iterable<T6>): Generator<[T1, T2, T3, T4, T5, T6]>;
221
+ declare function zip<T1, T2, T3, T4, T5, T6, T7>(mode: 'inner', source1: Iterable<T1>, source2: Iterable<T2>, source3: Iterable<T3>, source4: Iterable<T4>, source5: Iterable<T5>, source6: Iterable<T6>, source7: Iterable<T7>): Generator<[T1, T2, T3, T4, T5, T6, T7]>;
222
+ declare function zip<T1, T2, T3, T4, T5, T6, T7, T8>(mode: 'inner', source1: Iterable<T1>, source2: Iterable<T2>, source3: Iterable<T3>, source4: Iterable<T4>, source5: Iterable<T5>, source6: Iterable<T6>, source7: Iterable<T7>, source8: Iterable<T8>): Generator<[T1, T2, T3, T4, T5, T6, T7, T8]>;
223
+ declare function zip<T1, T2, T3, T4, T5, T6, T7, T8, T9>(mode: 'inner', source1: Iterable<T1>, source2: Iterable<T2>, source3: Iterable<T3>, source4: Iterable<T4>, source5: Iterable<T5>, source6: Iterable<T6>, source7: Iterable<T7>, source8: Iterable<T8>, source9: Iterable<T9>): Generator<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>;
224
+ declare function zip<T1, T2>(mode: 'outer', source1: Iterable<T1>, source2: Iterable<T2>): Generator<[T1 | undefined, T2 | undefined]>;
225
+ declare function zip<T1, T2, T3>(mode: 'outer', source1: Iterable<T1>, source2: Iterable<T2>, source3: Iterable<T3>): Generator<[T1 | undefined, T2 | undefined, T3 | undefined]>;
226
+ declare function zip<T1, T2, T3, T4>(mode: 'outer', source1: Iterable<T1>, source2: Iterable<T2>, source3: Iterable<T3>, source4: Iterable<T4>): Generator<[T1 | undefined, T2 | undefined, T3 | undefined, T4 | undefined]>;
227
+ declare function zip<T1, T2, T3, T4, T5>(mode: 'outer', source1: Iterable<T1>, source2: Iterable<T2>, source3: Iterable<T3>, source4: Iterable<T4>, source5: Iterable<T5>): Generator<[T1 | undefined, T2 | undefined, T3 | undefined, T4 | undefined, T5 | undefined]>;
228
+ declare function zip<T1, T2, T3, T4, T5, T6>(mode: 'outer', source1: Iterable<T1>, source2: Iterable<T2>, source3: Iterable<T3>, source4: Iterable<T4>, source5: Iterable<T5>, source6: Iterable<T6>): Generator<[T1 | undefined, T2 | undefined, T3 | undefined, T4 | undefined, T5 | undefined, T6 | undefined]>;
229
+ declare function zip<T1, T2, T3, T4, T5, T6, T7>(mode: 'outer', source1: Iterable<T1>, source2: Iterable<T2>, source3: Iterable<T3>, source4: Iterable<T4>, source5: Iterable<T5>, source6: Iterable<T6>, source7: Iterable<T7>): Generator<[
230
+ T1 | undefined,
231
+ T2 | undefined,
232
+ T3 | undefined,
233
+ T4 | undefined,
234
+ T5 | undefined,
235
+ T6 | undefined,
236
+ T7 | undefined
237
+ ]>;
238
+ declare function zip<T1, T2, T3, T4, T5, T6, T7, T8>(mode: 'outer', source1: Iterable<T1>, source2: Iterable<T2>, source3: Iterable<T3>, source4: Iterable<T4>, source5: Iterable<T5>, source6: Iterable<T6>, source7: Iterable<T7>, source8: Iterable<T8>): Generator<[
239
+ T1 | undefined,
240
+ T2 | undefined,
241
+ T3 | undefined,
242
+ T4 | undefined,
243
+ T5 | undefined,
244
+ T6 | undefined,
245
+ T7 | undefined,
246
+ T8 | undefined
247
+ ]>;
248
+ declare function zip<T1, T2, T3, T4, T5, T6, T7, T8, T9>(mode: 'outer', source1: Iterable<T1>, source2: Iterable<T2>, source3: Iterable<T3>, source4: Iterable<T4>, source5: Iterable<T5>, source6: Iterable<T6>, source7: Iterable<T7>, source8: Iterable<T8>, source9: Iterable<T9>): Generator<[
249
+ T1 | undefined,
250
+ T2 | undefined,
251
+ T3 | undefined,
252
+ T4 | undefined,
253
+ T5 | undefined,
254
+ T6 | undefined,
255
+ T7 | undefined,
256
+ T8 | undefined,
257
+ T9 | undefined
258
+ ]>;
259
+ /** Whether the sources yield pairwise-equal elements and end together. */
260
+ declare function sequenceEquals<T>(source1: Iterable<T>, source2: Iterable<T>, equals: Func<[left: T, right: T], boolean>): boolean;
261
+
262
+ export { concat, first, flattenMap, isAllThere, iterable, obj, replace, sequenceEquals, zip };
@@ -0,0 +1,119 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __returnValue = (v) => v;
3
+ function __exportSetter(name, newValue) {
4
+ this[name] = __returnValue.bind(null, newValue);
5
+ }
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true,
11
+ configurable: true,
12
+ set: __exportSetter.bind(all, name)
13
+ });
14
+ };
15
+
16
+ // src/flattenMap.ts
17
+ import { isFunction } from "@rhombus-toolkit/type-guards";
18
+
19
+ // src/obj.ts
20
+ var exports_obj = {};
21
+ __export(exports_obj, {
22
+ values: () => values,
23
+ keys: () => keys,
24
+ fromEntries: () => fromEntries,
25
+ entries: () => entries,
26
+ assign: () => assign
27
+ });
28
+ function keys(obj) {
29
+ return Object.keys(obj);
30
+ }
31
+ function values(obj) {
32
+ return Object.values(obj);
33
+ }
34
+ function entries(obj) {
35
+ return Object.entries(obj);
36
+ }
37
+ function fromEntries(entries2) {
38
+ return Object.fromEntries(entries2);
39
+ }
40
+ function assign(target, ...sources) {
41
+ return Object.assign(target, ...sources);
42
+ }
43
+
44
+ // src/flattenMap.ts
45
+ function join(a, b) {
46
+ return [a, b].filter(Boolean).join(".");
47
+ }
48
+ function flattenMap(map, leafPredicate = isFunction) {
49
+ const result = [];
50
+ const stack = Object.entries(map);
51
+ while (stack.length) {
52
+ const [prefix, branchOrLeaf] = stack.pop();
53
+ if (leafPredicate(branchOrLeaf)) {
54
+ result.push([prefix, branchOrLeaf]);
55
+ } else {
56
+ Object.entries(branchOrLeaf).forEach(([key, p]) => stack.push([join(prefix, key), p]));
57
+ }
58
+ }
59
+ return fromEntries(result);
60
+ }
61
+ // src/iterable.ts
62
+ import { isFunction as isFunction2, isIterable } from "@rhombus-toolkit/type-guards";
63
+ function* replace(source, match, replacement) {
64
+ const predicate = isFunction2(match) ? match : (item) => item === match;
65
+ for (const item of source) {
66
+ yield predicate(item) ? isFunction2(replacement) ? replacement(item) : replacement : item;
67
+ }
68
+ }
69
+ function first(source) {
70
+ for (const value of source) {
71
+ return value;
72
+ }
73
+ return;
74
+ }
75
+ function isAllThere(items) {
76
+ return Iterator.from(items).every((item) => item !== undefined);
77
+ }
78
+ function concat(...args) {
79
+ return Iterator.from(args).flatMap((item) => isIterable(item) ? Iterator.from(item) : [item]);
80
+ }
81
+ function iterable(fn) {
82
+ return { [Symbol.iterator]: fn };
83
+ }
84
+ function* zip(mode, ...sources) {
85
+ const iterators = sources.map((source) => Iterator.from(source));
86
+ while (true) {
87
+ const results = iterators.map((iterator) => iterator.next());
88
+ const ended = mode === "inner" ? results.some((result) => result.done) : results.every((result) => result.done);
89
+ if (ended) {
90
+ return;
91
+ }
92
+ yield results.map((result) => result.value);
93
+ }
94
+ }
95
+ function sequenceEquals(source1, source2, equals) {
96
+ const left = Iterator.from(source1);
97
+ const right = Iterator.from(source2);
98
+ while (true) {
99
+ const first2 = left.next();
100
+ const second = right.next();
101
+ if (first2.done || second.done) {
102
+ return (first2.done ?? false) === (second.done ?? false);
103
+ }
104
+ if (!equals(first2.value, second.value)) {
105
+ return false;
106
+ }
107
+ }
108
+ }
109
+ export {
110
+ zip,
111
+ sequenceEquals,
112
+ replace,
113
+ exports_obj as obj,
114
+ iterable,
115
+ isAllThere,
116
+ flattenMap,
117
+ first,
118
+ concat
119
+ };
package/package.json CHANGED
@@ -1,9 +1,7 @@
1
1
  {
2
2
  "name": "@rhombus-toolkit/obj",
3
- "version": "0.0.0-placeholder.0",
4
- "description": "PLACEHOLDER name reservation only. Real content lands in a 1.0.0-next release.",
5
- "license": "MIT",
6
- "author": "Thomas Butler",
3
+ "version": "1.0.1",
4
+ "description": "Typed counterparts of the Object.* statics, plus flattenMap.",
7
5
  "repository": {
8
6
  "type": "git",
9
7
  "url": "https://github.com/rhombus-toolkit/ts.git",
@@ -11,10 +9,31 @@
11
9
  },
12
10
  "type": "module",
13
11
  "sideEffects": false,
12
+ "main": "./dist/bundle/index.js",
13
+ "types": "./dist/bundle/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/bundle/index.d.ts",
17
+ "import": "./dist/bundle/index.js",
18
+ "default": "./dist/bundle/index.js"
19
+ }
20
+ },
14
21
  "files": [
15
- "README.md"
22
+ "dist"
16
23
  ],
24
+ "keywords": [],
25
+ "author": "Thomas Butler",
26
+ "dependencies": {
27
+ "@rhombus-toolkit/type-guards": "2.0.1",
28
+ "@rhombus-toolkit/types": "1.0.1"
29
+ },
17
30
  "publishConfig": {
18
- "access": "public"
31
+ "access": "public",
32
+ "provenance": true
33
+ },
34
+ "scripts": {
35
+ "build": "bun ../../scripts/build-lib.ts",
36
+ "lint": "bun x tsc --noEmit -p tsconfig.ci.json",
37
+ "test": "bun test"
19
38
  }
20
- }
39
+ }
package/README.md DELETED
@@ -1,13 +0,0 @@
1
- # @rhombus-toolkit/obj
2
-
3
- **This version is a placeholder. It contains no code.**
4
-
5
- It exists only to reserve the package name so that npm Trusted Publishing can be
6
- configured ahead of the first real release. Do not depend on this version.
7
-
8
- Real content ships as `1.0.0-next.x` on the `next` dist-tag.
9
-
10
- This package will hold the typed counterparts of the `Object.*` statics —
11
- `keys`, `values`, `entries`, `fromEntries`, `assign` — each a type and a wrapper
12
- function declaration-merged under one name, moved out of
13
- `@rhombus-toolkit/type-helpers`.