@cascateer/lib 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.
@@ -0,0 +1,36 @@
1
+ name: Publish to NPM
2
+
3
+ on:
4
+ workflow_call:
5
+ push:
6
+ tags:
7
+ - "v*"
8
+
9
+ jobs:
10
+ publish:
11
+ runs-on: ubuntu-latest
12
+ permissions:
13
+ contents: write
14
+ id-token: write
15
+
16
+ steps:
17
+ - uses: actions/checkout@v6
18
+ - uses: actions/setup-node@v6
19
+ with:
20
+ node-version: "24"
21
+ registry-url: "https://registry.npmjs.org"
22
+
23
+ - name: Verify version matches tag
24
+ run: |
25
+ TAG="${GITHUB_REF#refs/tags/}"
26
+ VERSION="${TAG#v}"
27
+ FILE_VERSION=$(node -p "require('./package.json').version")
28
+ if [ "$VERSION" != "$FILE_VERSION" ]; then
29
+ echo "Version mismatch: tag=$VERSION, package.json=$FILE_VERSION"
30
+ exit 1
31
+ fi
32
+
33
+ - name: Publish to NPM
34
+ env:
35
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
36
+ run: npm publish --access public --provenance
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "@cascateer/lib",
3
+ "version": "1.0.1",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/cascateer/lib.git"
7
+ },
8
+ "scripts": {
9
+ "patch": "npm version patch && git push origin main --tags"
10
+ },
11
+ "exports": {
12
+ ".": "./src/index.ts"
13
+ },
14
+ "dependencies": {
15
+ "lodash": "^4.18.1",
16
+ "rxjs": "^7.8.2"
17
+ },
18
+ "devDependencies": {
19
+ "@types/lodash": "^4.17.24"
20
+ }
21
+ }
@@ -0,0 +1,56 @@
1
+ import { Dictionary, once } from "lodash";
2
+ import { AsyncSubject, lastValueFrom, UnaryFunction } from "rxjs";
3
+ import { keys } from "./keys";
4
+
5
+ export type Extend<T, U> = Omit<T, keyof U> & U;
6
+
7
+ export class ExtendableDictionary<T, U extends Dictionary<T>> {
8
+ constructor(
9
+ public currentValue: U,
10
+ private value = new AsyncSubject<Dictionary<T>>(),
11
+ ) {}
12
+
13
+ complete = once((): U => {
14
+ this.value.next(this.currentValue);
15
+ this.value.complete();
16
+
17
+ return this.currentValue;
18
+ });
19
+
20
+ extend<V extends Dictionary<T>>(
21
+ value: (
22
+ currentValue: U,
23
+ ) => ({
24
+ property,
25
+ }: {
26
+ property: (constructor: UnaryFunction<Promise<string>, T>) => T;
27
+ }) => V,
28
+ ) {
29
+ return new ExtendableDictionary<T, Extend<U, V>>(
30
+ {
31
+ ...this.currentValue,
32
+ ...value(this.currentValue)({
33
+ property: (constructor) => {
34
+ const property = constructor(
35
+ lastValueFrom(this.value).then(
36
+ (value) =>
37
+ new Promise<string>((resolve, reject) => {
38
+ for (const key of keys(value)) {
39
+ if (value[key] === property) {
40
+ return resolve(key);
41
+ }
42
+ }
43
+
44
+ reject();
45
+ }),
46
+ ),
47
+ );
48
+
49
+ return property;
50
+ },
51
+ }),
52
+ },
53
+ this.value,
54
+ );
55
+ }
56
+ }
package/src/array.ts ADDED
@@ -0,0 +1,4 @@
1
+ export type MaybeArray<T> = T | T[];
2
+
3
+ export const asArray = <T>(array: MaybeArray<T>): Array<T> =>
4
+ Array.isArray(array) ? array : [array];
@@ -0,0 +1,23 @@
1
+ import { Comparator, uniqWith } from "lodash";
2
+
3
+ export const chunkWith = <T>(items: T[], comparator?: Comparator<T>): T[][] => [
4
+ ...{
5
+ *[Symbol.iterator]() {
6
+ const chunk = new Array<T>();
7
+
8
+ if (items.length == 0) {
9
+ return;
10
+ }
11
+
12
+ for (const item of items) {
13
+ if (uniqWith([...chunk, item], comparator).length === 1) {
14
+ chunk.push(item);
15
+ } else {
16
+ yield chunk.splice(0, chunk.length, item);
17
+ }
18
+ }
19
+
20
+ yield chunk;
21
+ },
22
+ },
23
+ ];
package/src/index.ts ADDED
@@ -0,0 +1,13 @@
1
+ export { asArray, type MaybeArray } from "./array";
2
+ export { chunkWith } from "./chunkWith";
3
+ export { ExtendableDictionary } from "./ExtendableDictionary";
4
+ export { keys } from "./keys";
5
+ export { nonNullable, nonNullableAsync } from "./nonNullable";
6
+ export { nthArg } from "./nthArg";
7
+ export {
8
+ asObservable,
9
+ type MaybeObservable,
10
+ type MaybeObservableInput,
11
+ type MaybeObservableInputTuple,
12
+ } from "./observable";
13
+ export { property } from "./property";
package/src/keys.ts ADDED
@@ -0,0 +1,7 @@
1
+ export const keys = <T>(value: T) => [
2
+ ...{
3
+ *[Symbol.iterator]() {
4
+ for (const key in value) yield key;
5
+ },
6
+ },
7
+ ];
@@ -0,0 +1,10 @@
1
+ export const nonNullable = <T>(value: T): NonNullable<T> => {
2
+ if (value == null) {
3
+ throw null;
4
+ }
5
+
6
+ return value;
7
+ };
8
+
9
+ export const nonNullableAsync = async <T>(value: T): Promise<NonNullable<T>> =>
10
+ nonNullable(value);
package/src/nthArg.ts ADDED
@@ -0,0 +1,6 @@
1
+ export function nthArg<T>(n: 0): (arg0: T) => T;
2
+ export function nthArg<T>(n: 1): (arg0: any, arg1: T) => T;
3
+ export function nthArg<T>(n: 2): (arg0: any, arg1: any, arg2: T) => T;
4
+ export function nthArg<T>(n: number): (...args: any[]) => T {
5
+ return (...args) => args[n];
6
+ }
@@ -0,0 +1,12 @@
1
+ import { isObservable, Observable, ObservableInput, of } from "rxjs";
2
+
3
+ export const asObservable = <T>(value: MaybeObservable<T>): Observable<T> =>
4
+ isObservable(value) ? value : of(value);
5
+
6
+ export type MaybeObservable<T> = T | Observable<T>;
7
+
8
+ export type MaybeObservableInput<T> = T | ObservableInput<T>;
9
+
10
+ export type MaybeObservableInputTuple<T> = {
11
+ [K in keyof T]: MaybeObservableInput<T[K]>;
12
+ };
@@ -0,0 +1,4 @@
1
+ export const property =
2
+ <T, K extends keyof T = keyof T>(key: K) =>
3
+ (value: T): T[K] =>
4
+ value[key];
package/tsconfig.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2016",
4
+ "module": "commonjs",
5
+ "types": ["node"],
6
+ "esModuleInterop": true,
7
+ "forceConsistentCasingInFileNames": true,
8
+ "strict": true,
9
+ "skipLibCheck": true,
10
+ "noUncheckedIndexedAccess": true
11
+ }
12
+ }