@dayme/alien-utils 0.1.0 → 0.2.0

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/README.md CHANGED
@@ -1,98 +1,98 @@
1
- # @dayme/alien-utils
2
-
3
- TypeScript utility library with functional programming data structures (Option, Result, Iter, Stack, Queue, Bimap, Match, Dispatch).
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install @dayme/alien-utils
9
- # or
10
- bun add @dayme/alien-utils
11
- # or
12
- pnpm add @dayme/alien-utils
13
- ```
14
-
15
- ## Usage
16
-
17
- ```typescript
18
- import { Option, Result, Iter, Stack, Queue } from "@dayme/alien-utils";
19
-
20
- // Option - Handle nullable values
21
- const maybeValue = Option.from("hello");
22
- const doubled = maybeValue.map(s => s.length * 2); // Some(10)
23
-
24
- // Result - Handle errors
25
- const result = Result.ok(42);
26
- const value = result.unwrapOr(0); // 42
27
-
28
- // Iter - Lazy transformations
29
- Iter.from([1, 2, 3])
30
- .map(x => x * 2)
31
- .filter(x => x > 3)
32
- .collect(); // [4, 6]
33
-
34
- // Stack - LIFO
35
- const stack = new Stack<number>();
36
- stack.push(1).push(2);
37
- stack.pop(); // Some(2)
38
-
39
- // Queue - FIFO
40
- const queue = new Queue<number>();
41
- queue.enqueue(1).enqueue(2);
42
- queue.dequeue(); // Some(1)
43
- ```
44
-
45
- ## Documentation
46
-
47
- **[View Documentation](https://lisovskiyivan.github.io/alien-utils/)**
48
-
49
- ## Development
50
-
51
- ```bash
52
- # Install dependencies
53
- bun install
54
-
55
- # Build library
56
- bun run build
57
-
58
- # Watch mode (TypeScript + Vite)
59
- bun run dev
60
-
61
- # Run tests
62
- bun test
63
-
64
- # Run tests in watch mode
65
- bun test --watch
66
-
67
- # Playground for testing the package
68
- # First build the package: bun run build
69
- # Then run playground: bun run playground
70
- bun run playground
71
-
72
- # Development documentation
73
- bun run docs:dev
74
-
75
- # Build documentation
76
- bun run docs:build
77
-
78
- # Preview documentation
79
- bun run docs:preview
80
- ```
81
-
82
- ## Testing
83
-
84
- Tests are written using Bun's built-in test framework:
85
-
86
- ```bash
87
- # Run all tests
88
- bun test
89
-
90
- # Run tests in watch mode
91
- bun test --watch
92
- ```
93
-
94
- Tests cover all methods of `Option` (Some/None), `Result` (Ok/Err), and other classes, including practical usage examples.
95
-
96
- ## License
97
-
98
- MIT
1
+ # @dayme/alien-utils
2
+
3
+ TypeScript utility library with functional programming data structures (Option, Result, Iter, Stack, Queue, Bimap, Match, Dispatch).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @dayme/alien-utils
9
+ # or
10
+ bun add @dayme/alien-utils
11
+ # or
12
+ pnpm add @dayme/alien-utils
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```typescript
18
+ import { Option, Result, Iter, Stack, Queue } from "@dayme/alien-utils";
19
+
20
+ // Option - Handle nullable values
21
+ const maybeValue = Option.from("hello");
22
+ const doubled = maybeValue.map(s => s.length * 2); // Some(10)
23
+
24
+ // Result - Handle errors
25
+ const result = Result.ok(42);
26
+ const value = result.unwrapOr(0); // 42
27
+
28
+ // Iter - Lazy transformations
29
+ Iter.from([1, 2, 3])
30
+ .map(x => x * 2)
31
+ .filter(x => x > 3)
32
+ .collect(); // [4, 6]
33
+
34
+ // Stack - LIFO
35
+ const stack = new Stack<number>();
36
+ stack.push(1).push(2);
37
+ stack.pop(); // Some(2)
38
+
39
+ // Queue - FIFO
40
+ const queue = new Queue<number>();
41
+ queue.enqueue(1).enqueue(2);
42
+ queue.dequeue(); // Some(1)
43
+ ```
44
+
45
+ ## Documentation
46
+
47
+ **[View Documentation](https://lisovskiyivan.github.io/alien-utils/)**
48
+
49
+ ## Development
50
+
51
+ ```bash
52
+ # Install dependencies
53
+ bun install
54
+
55
+ # Build library
56
+ bun run build
57
+
58
+ # Watch mode (TypeScript + Vite)
59
+ bun run dev
60
+
61
+ # Run tests
62
+ bun test
63
+
64
+ # Run tests in watch mode
65
+ bun test --watch
66
+
67
+ # Playground for testing the package
68
+ # First build the package: bun run build
69
+ # Then run playground: bun run playground
70
+ bun run playground
71
+
72
+ # Development documentation
73
+ bun run docs:dev
74
+
75
+ # Build documentation
76
+ bun run docs:build
77
+
78
+ # Preview documentation
79
+ bun run docs:preview
80
+ ```
81
+
82
+ ## Testing
83
+
84
+ Tests are written using Bun's built-in test framework:
85
+
86
+ ```bash
87
+ # Run all tests
88
+ bun test
89
+
90
+ # Run tests in watch mode
91
+ bun test --watch
92
+ ```
93
+
94
+ Tests cover all methods of `Option` (Some/None), `Result` (Ok/Err), and other classes, including practical usage examples.
95
+
96
+ ## License
97
+
98
+ MIT
@@ -0,0 +1,83 @@
1
+ export interface HistoryOptions<T> {
2
+ limit?: number;
3
+ equals?: (a: T, b: T) => boolean;
4
+ }
5
+ export interface Patch {
6
+ op: "add" | "remove" | "replace";
7
+ path: string;
8
+ value?: unknown;
9
+ oldValue?: unknown;
10
+ }
11
+ export interface PatchHistoryOptions<T> {
12
+ limit?: number;
13
+ diff: (oldValue: T, newValue: T) => Patch[];
14
+ apply: (state: T, patches: Patch[]) => T;
15
+ invert: (patches: Patch[]) => Patch[];
16
+ }
17
+ type Subscriber<T> = (state: T) => void;
18
+ type TransactionFn = () => void;
19
+ export declare class History<T> {
20
+ private states;
21
+ private currentIndex;
22
+ private limit;
23
+ private equals;
24
+ private subscribers;
25
+ private inTransaction;
26
+ private transactionQueue;
27
+ private transactionStates;
28
+ constructor(initial: T, options?: HistoryOptions<T>);
29
+ get state(): T;
30
+ get index(): number;
31
+ get length(): number;
32
+ set(next: T): void;
33
+ private _addToHistory;
34
+ private _set;
35
+ update(draft: (state: T) => T): void;
36
+ private _update;
37
+ undo(): void;
38
+ private _undo;
39
+ redo(): void;
40
+ private _redo;
41
+ get canUndo(): boolean;
42
+ get canRedo(): boolean;
43
+ subscribe(subscriber: Subscriber<T>): () => void;
44
+ private _notify;
45
+ transaction(fn: TransactionFn): void;
46
+ clear(): void;
47
+ static from<T>(iterable: Iterable<T>, options?: HistoryOptions<T>): History<T>;
48
+ static withPatches<T>(initial: T, options: PatchHistoryOptions<T>): PatchHistory<T>;
49
+ }
50
+ export declare class PatchHistory<T> {
51
+ private currentState;
52
+ private patches;
53
+ private currentIndex;
54
+ private limit;
55
+ private diff;
56
+ private apply;
57
+ private invert;
58
+ private subscribers;
59
+ private inTransaction;
60
+ private transactionQueue;
61
+ private transactionStates;
62
+ constructor(initial: T, options: PatchHistoryOptions<T>);
63
+ get state(): T;
64
+ get index(): number;
65
+ get length(): number;
66
+ set(next: T): void;
67
+ private _addToHistory;
68
+ private _set;
69
+ update(draft: (state: T) => T): void;
70
+ private _update;
71
+ undo(): void;
72
+ private _undo;
73
+ redo(): void;
74
+ private _redo;
75
+ get canUndo(): boolean;
76
+ get canRedo(): boolean;
77
+ subscribe(subscriber: Subscriber<T>): () => void;
78
+ private _notify;
79
+ transaction(fn: TransactionFn): void;
80
+ clear(): void;
81
+ }
82
+ export {};
83
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/package/history/history.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { History, PatchHistory } from './history';
2
+ export type { HistoryOptions, Patch, PatchHistoryOptions } from './history';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/package/history/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.d.ts CHANGED
@@ -6,4 +6,5 @@ export * from './dispatch/index';
6
6
  export * from './bimap/index';
7
7
  export * from './stack/index';
8
8
  export * from './queue/index';
9
+ export * from './history/index';
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/package/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/package/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -1064,5 +1064,242 @@ var Bimap = class e {
1064
1064
  for (let n of e) t.enqueue(n);
1065
1065
  return t;
1066
1066
  }
1067
+ }, History = class e {
1068
+ states;
1069
+ currentIndex;
1070
+ limit;
1071
+ equals;
1072
+ subscribers;
1073
+ inTransaction;
1074
+ transactionQueue;
1075
+ transactionStates;
1076
+ constructor(e, t = {}) {
1077
+ this.states = [e], this.currentIndex = 0, this.limit = t.limit ?? Infinity, this.equals = t.equals ?? Object.is, this.subscribers = /* @__PURE__ */ new Set(), this.inTransaction = !1, this.transactionQueue = [], this.transactionStates = [];
1078
+ }
1079
+ get state() {
1080
+ return this.inTransaction && this.transactionStates.length > 0 ? this.transactionStates[this.transactionStates.length - 1] : this.states[this.currentIndex];
1081
+ }
1082
+ get index() {
1083
+ return this.currentIndex;
1084
+ }
1085
+ get length() {
1086
+ return this.states.length;
1087
+ }
1088
+ set(e) {
1089
+ if (this.inTransaction) {
1090
+ this.transactionQueue.push(() => this._set(e));
1091
+ return;
1092
+ }
1093
+ this._set(e);
1094
+ }
1095
+ _addToHistory(e) {
1096
+ this.equals(this.state, e) || (this.currentIndex < this.states.length - 1 ? (this.states[this.currentIndex] = e, this.states = this.states.slice(0, this.currentIndex + 1)) : (this.states.push(e), this.currentIndex++), this.states.length > this.limit && (this.states.shift(), this.currentIndex > 0 && this.currentIndex--), this._notify());
1097
+ }
1098
+ _set(e) {
1099
+ if (this.inTransaction) {
1100
+ this.transactionStates.push(e);
1101
+ return;
1102
+ }
1103
+ this._addToHistory(e);
1104
+ }
1105
+ update(e) {
1106
+ if (this.inTransaction) {
1107
+ this.transactionQueue.push(() => this._update(e));
1108
+ return;
1109
+ }
1110
+ this._update(e);
1111
+ }
1112
+ _update(e) {
1113
+ let t = e(this.state);
1114
+ this._set(t);
1115
+ }
1116
+ undo() {
1117
+ if (this.inTransaction) {
1118
+ this.transactionQueue.push(() => this._undo());
1119
+ return;
1120
+ }
1121
+ this._undo();
1122
+ }
1123
+ _undo() {
1124
+ this.currentIndex > 0 && (this.currentIndex--, this._notify());
1125
+ }
1126
+ redo() {
1127
+ if (this.inTransaction) {
1128
+ this.transactionQueue.push(() => this._redo());
1129
+ return;
1130
+ }
1131
+ this._redo();
1132
+ }
1133
+ _redo() {
1134
+ this.currentIndex < this.states.length - 1 && (this.currentIndex++, this._notify());
1135
+ }
1136
+ get canUndo() {
1137
+ return this.currentIndex > 0;
1138
+ }
1139
+ get canRedo() {
1140
+ return this.currentIndex < this.states.length - 1;
1141
+ }
1142
+ subscribe(e) {
1143
+ return this.subscribers.add(e), () => {
1144
+ this.subscribers.delete(e);
1145
+ };
1146
+ }
1147
+ _notify() {
1148
+ for (let e of this.subscribers) e(this.state);
1149
+ }
1150
+ transaction(e) {
1151
+ if (this.inTransaction) {
1152
+ e();
1153
+ return;
1154
+ }
1155
+ this.inTransaction = !0, this.transactionQueue = [], this.transactionStates = [];
1156
+ try {
1157
+ e();
1158
+ for (let e of this.transactionQueue) e();
1159
+ } finally {
1160
+ if (this.inTransaction = !1, this.transactionStates.length > 0) {
1161
+ let e = this.transactionStates[this.transactionStates.length - 1];
1162
+ this._addToHistory(e);
1163
+ }
1164
+ this.transactionQueue = [], this.transactionStates = [];
1165
+ }
1166
+ }
1167
+ clear() {
1168
+ this.states = [this.states[this.currentIndex]], this.currentIndex = 0;
1169
+ }
1170
+ static from(t, n) {
1171
+ let r = Array.from(t);
1172
+ if (r.length === 0) throw Error("Cannot create History from empty iterable");
1173
+ let i = new e(r[0], n);
1174
+ for (let e = 1; e < r.length; e++) i._set(r[e]);
1175
+ return i;
1176
+ }
1177
+ static withPatches(e, t) {
1178
+ return new PatchHistory(e, t);
1179
+ }
1180
+ }, PatchHistory = class {
1181
+ currentState;
1182
+ patches;
1183
+ currentIndex;
1184
+ limit;
1185
+ diff;
1186
+ apply;
1187
+ invert;
1188
+ subscribers;
1189
+ inTransaction;
1190
+ transactionQueue;
1191
+ transactionStates;
1192
+ constructor(e, t) {
1193
+ this.currentState = e, this.patches = [[]], this.currentIndex = 0, this.limit = t.limit ?? Infinity, this.diff = t.diff, this.apply = t.apply, this.invert = t.invert, this.subscribers = /* @__PURE__ */ new Set(), this.inTransaction = !1, this.transactionQueue = [], this.transactionStates = [];
1194
+ }
1195
+ get state() {
1196
+ return this.inTransaction && this.transactionStates.length > 0 ? this.transactionStates[this.transactionStates.length - 1] : this.currentState;
1197
+ }
1198
+ get index() {
1199
+ return this.currentIndex;
1200
+ }
1201
+ get length() {
1202
+ return this.patches.length;
1203
+ }
1204
+ set(e) {
1205
+ if (this.inTransaction) {
1206
+ this.transactionQueue.push(() => this._set(e));
1207
+ return;
1208
+ }
1209
+ this._set(e);
1210
+ }
1211
+ _addToHistory(e) {
1212
+ let t = this.diff(this.currentState, e);
1213
+ if (t.length !== 0) {
1214
+ if (this.currentIndex < this.patches.length - 1) this.patches[this.currentIndex] = t, this.patches = this.patches.slice(0, this.currentIndex + 1), this.currentState = e;
1215
+ else {
1216
+ if (this.patches.length === this.limit) {
1217
+ let e = this.patches.shift();
1218
+ this.currentIndex > 0 && this.currentIndex--, e.length > 0 && (this.currentState = this.apply(this.currentState, this.invert(e)));
1219
+ }
1220
+ this.patches.push(t), this.currentIndex++, this.currentState = e;
1221
+ }
1222
+ this._notify();
1223
+ }
1224
+ }
1225
+ _set(e) {
1226
+ if (this.inTransaction) {
1227
+ this.transactionStates.push(e);
1228
+ return;
1229
+ }
1230
+ this._addToHistory(e);
1231
+ }
1232
+ update(e) {
1233
+ if (this.inTransaction) {
1234
+ this.transactionQueue.push(() => this._update(e));
1235
+ return;
1236
+ }
1237
+ this._update(e);
1238
+ }
1239
+ _update(e) {
1240
+ let t = e(this.state);
1241
+ this._set(t);
1242
+ }
1243
+ undo() {
1244
+ if (this.inTransaction) {
1245
+ this.transactionQueue.push(() => this._undo());
1246
+ return;
1247
+ }
1248
+ this._undo();
1249
+ }
1250
+ _undo() {
1251
+ if (this.currentIndex > 0) {
1252
+ let e = this.patches[this.currentIndex];
1253
+ this.currentState = this.apply(this.currentState, this.invert(e)), this.currentIndex--, this._notify();
1254
+ }
1255
+ }
1256
+ redo() {
1257
+ if (this.inTransaction) {
1258
+ this.transactionQueue.push(() => this._redo());
1259
+ return;
1260
+ }
1261
+ this._redo();
1262
+ }
1263
+ _redo() {
1264
+ if (this.currentIndex < this.patches.length - 1) {
1265
+ this.currentIndex++;
1266
+ let e = this.patches[this.currentIndex];
1267
+ this.currentState = this.apply(this.currentState, e), this._notify();
1268
+ }
1269
+ }
1270
+ get canUndo() {
1271
+ return this.currentIndex > 0;
1272
+ }
1273
+ get canRedo() {
1274
+ return this.currentIndex < this.patches.length - 1;
1275
+ }
1276
+ subscribe(e) {
1277
+ return this.subscribers.add(e), () => {
1278
+ this.subscribers.delete(e);
1279
+ };
1280
+ }
1281
+ _notify() {
1282
+ for (let e of this.subscribers) e(this.state);
1283
+ }
1284
+ transaction(e) {
1285
+ if (this.inTransaction) {
1286
+ e();
1287
+ return;
1288
+ }
1289
+ this.inTransaction = !0, this.transactionQueue = [], this.transactionStates = [];
1290
+ try {
1291
+ e();
1292
+ for (let e of this.transactionQueue) e();
1293
+ } finally {
1294
+ if (this.inTransaction = !1, this.transactionStates.length > 0) {
1295
+ let e = this.transactionStates[this.transactionStates.length - 1];
1296
+ this._addToHistory(e);
1297
+ }
1298
+ this.transactionQueue = [], this.transactionStates = [];
1299
+ }
1300
+ }
1301
+ clear() {
1302
+ this.patches = [this.patches[this.currentIndex]], this.currentIndex = 0;
1303
+ }
1067
1304
  };
1068
- export { Bimap, Err, Iter, None, Ok, Queue, Some, Stack, dispatch, isArray, isBoolean, isFunction, isNull, isNumber, isObject, isString, isUndefined, match };
1305
+ export { Bimap, Err, History, Iter, None, Ok, PatchHistory, Queue, Some, Stack, dispatch, isArray, isBoolean, isFunction, isNull, isNumber, isObject, isString, isUndefined, match };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dayme/alien-utils",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "TypeScript utility library with functional programming data structures (Option, Result, Iter, Stack, Queue, Bimap, Match, Dispatch)",
6
6
  "keywords": [