doit-lib 1.0.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.
@@ -0,0 +1,55 @@
1
+ export type PathToken = {
2
+ type: 'key';
3
+ value: string;
4
+ } | {
5
+ type: 'index';
6
+ value: number;
7
+ } | {
8
+ type: 'filter';
9
+ key: string;
10
+ value: any;
11
+ };
12
+ export type Operation = {
13
+ op: 'set';
14
+ path: string;
15
+ value: any;
16
+ } | {
17
+ op: 'delete';
18
+ path: string;
19
+ } | {
20
+ op: 'batch';
21
+ ops: Operation[];
22
+ };
23
+ export declare class DoIt {
24
+ private state;
25
+ private undoStack;
26
+ private redoStack;
27
+ private maxHistory;
28
+ private listeners;
29
+ private pathCache;
30
+ private historyDirty;
31
+ private cachedHistory;
32
+ constructor(initialState?: any, options?: {
33
+ maxHistory?: number;
34
+ });
35
+ getState(): any;
36
+ getHistory(): any;
37
+ set(path: string, value: any): void;
38
+ undo(): boolean;
39
+ redo(): boolean;
40
+ clearHistory(): void;
41
+ subscribe(fn: (state: any, history: any) => void): () => void;
42
+ private notify;
43
+ private getParsedPath;
44
+ private cloneValue;
45
+ }
46
+ export declare function parsePath(path: string): PathToken[];
47
+ export declare function reconstructPath(tokens: PathToken[]): string;
48
+ interface ProbeResult {
49
+ exists: boolean;
50
+ value: any;
51
+ missingIndex: number;
52
+ }
53
+ export declare function probe(obj: any, tokens: PathToken[]): ProbeResult;
54
+ export declare function applyOperation(obj: any, operation: Operation): void;
55
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ var h=/([^\.\[\]]+)|\[(\d+)\]|\[(\w+):([^\]]+)\]/g,u=class{constructor(e={},i={}){this.undoStack=[];this.redoStack=[];this.listeners=[];this.pathCache=new Map;this.historyDirty=!0;this.state=e,this.maxHistory=i.maxHistory||100}getState(){return this.state}getHistory(){return this.historyDirty?(this.cachedHistory={undo:this.undoStack.length,redo:this.redoStack.length,canUndo:this.undoStack.length>0,canRedo:this.redoStack.length>0},this.historyDirty=!1,this.cachedHistory):this.cachedHistory}set(e,i){let t=this.getParsedPath(e),s=d(this.state,t),n;if(s.missingIndex!==-1){let p=t[s.missingIndex];n={op:"delete",path:f(t.slice(0,s.missingIndex+1))}}else n={op:"set",path:e,value:this.cloneValue(s.value)};let a={op:"set",path:e,value:i};l(this.state,a),this.undoStack.push({undo:n,redo:a}),this.redoStack=[],this.undoStack.length>this.maxHistory&&this.undoStack.shift(),this.notify()}undo(){if(this.undoStack.length===0)return!1;let e=this.undoStack.pop();return l(this.state,e.undo),this.redoStack.push(e),this.notify(),!0}redo(){if(this.redoStack.length===0)return!1;let e=this.redoStack.pop();return l(this.state,e.redo),this.undoStack.push(e),this.notify(),!0}clearHistory(){this.undoStack=[],this.redoStack=[],this.pathCache.clear(),this.notify()}subscribe(e){return this.listeners.push(e),()=>{this.listeners=this.listeners.filter(i=>i!==e)}}notify(){this.historyDirty=!0;let e=this.getHistory();this.listeners.forEach(i=>i(this.state,e))}getParsedPath(e){let i=this.pathCache.get(e);if(!i&&(i=y(e),this.pathCache.set(e,i),this.pathCache.size>1e3)){let t=this.pathCache.keys().next().value;this.pathCache.delete(t)}return i}cloneValue(e){if(e==null||typeof e!="object")return e;if(Array.isArray(e))return e.map(t=>this.cloneValue(t));if(Array.isArray(e))return e.map(t=>this.cloneValue(t));let i={};for(let t in e)e.hasOwnProperty(t)&&(i[t]=this.cloneValue(e[t]));return i}};function y(r){let e=[],i;for(;i=h.exec(r);)if(i[1])e.push({type:"key",value:i[1]});else if(i[2])e.push({type:"index",value:Number(i[2])});else if(i[3]){let t=i[4];isNaN(Number(t))?(t.startsWith("'")&&t.endsWith("'")||t.startsWith('"')&&t.endsWith('"'))&&(t=t.slice(1,-1)):t=Number(t),e.push({type:"filter",key:i[3],value:t})}return e}function f(r){return r.map((e,i)=>{if(e.type==="key")return(i>0?".":"")+e.value;if(e.type==="index")return`[${e.value}]`;if(e.type==="filter"){let t=typeof e.value=="string"?`"${e.value}"`:e.value;return`[${e.key}:${t}]`}return""}).join("")}function d(r,e){let i=r;for(let t=0;t<e.length;t++){let s=e[t];if(i==null)return{exists:!1,value:void 0,missingIndex:t};if(s.type==="key"){if(!(s.value in i))return{exists:!1,value:void 0,missingIndex:t};i=i[s.value]}else if(s.type==="index"){if(!Array.isArray(i))return{exists:!1,value:void 0,missingIndex:t};if(s.value<0||s.value>=i.length)return{exists:!1,value:void 0,missingIndex:t};i=i[s.value]}else if(s.type==="filter"){if(!Array.isArray(i))return{exists:!1,value:void 0,missingIndex:t};let n=i.find(a=>a[s.key]==s.value);if(!n)return{exists:!1,value:void 0,missingIndex:t};i=n}}return{exists:!0,value:i,missingIndex:-1}}function l(r,e){if(e.op==="batch"){e.ops.forEach(s=>l(r,s));return}let i=y(e.path),t=r;if(e.op==="delete"){for(let n=0;n<i.length-1;n++){let a=i[n];if(t=o(t,a,!1),!t)return}let s=i[i.length-1];if(s.type==="key")delete t[s.value];else if(s.type==="index")Array.isArray(t)&&t.splice(s.value,1);else if(s.type==="filter"&&Array.isArray(t)){let n=t.findIndex(a=>a[s.key]==s.value);n!==-1&&t.splice(n,1)}}else if(e.op==="set"){for(let n=0;n<i.length-1;n++){let a=i[n];t=o(t,a,!0)}let s=i[i.length-1];if(s.type==="key")t[s.value]=e.value;else if(s.type==="index")t[s.value]=e.value;else if(s.type==="filter"&&Array.isArray(t)){let n=t.find(a=>a&&a[s.key]==s.value);if(n||(n={[s.key]:s.value},t.push(n)),typeof e.value=="object"&&!Array.isArray(e.value))Object.assign(n,e.value);else{let a=t.indexOf(n);t[a]={...n,...e.value}}}}}function o(r,e,i){if(e.type==="key")return(r[e.value]===void 0||typeof r[e.value]!="object")&&i&&(r[e.value]={}),r[e.value];if(e.type==="index")return i&&r[e.value]===void 0&&(r[e.value]={}),r[e.value];if(e.type==="filter"){if(!Array.isArray(r))return;let t=r.find(s=>s[e.key]==e.value);return!t&&i&&(t={[e.key]:e.value},r.push(t)),t}}export{u as DoIt,l as applyOperation,y as parsePath,d as probe,f as reconstructPath};
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "doit-lib",
3
+ "version": "1.0.0",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "type": "module",
7
+ "scripts": {
8
+ "test": "vitest run",
9
+ "build": "tsc --emitDeclarationOnly && esbuild src/index.ts --bundle --minify --format=esm --outfile=dist/index.js",
10
+ "build-obfus": "tsc --emitDeclarationOnly && node build.mjs"
11
+ },
12
+ "keywords": [],
13
+ "author": {
14
+ "name": "Khalif",
15
+ "email": "",
16
+ "url": "https://github.com/khalifmv"
17
+ },
18
+ "license": "MIT",
19
+ "description": "",
20
+ "files": ["dist"],
21
+ "devDependencies": {
22
+ "@types/node": "^25.0.3",
23
+ "esbuild": "^0.27.2",
24
+ "javascript-obfuscator": "^5.1.0",
25
+ "terser": "^5.44.1",
26
+ "typescript": "^5.9.3",
27
+ "vitest": "^4.0.16"
28
+ }
29
+ }