@nine-lab/nine-util 0.2.0 → 0.4.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/dist/nine-util.js CHANGED
@@ -8,48 +8,45 @@ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "
8
8
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
9
9
  var _name, _color, _enabled, _timer, _queue, _delay, _TaskDebouncer_instances, flush_fn;
10
10
  class Trace {
11
- // 현재 상태 저장용
12
- constructor(name = "nine-util", color = "#4CAF50") {
11
+ // 👈 상태값이 기준이 됩니다.
12
+ constructor(name = "nine-util", color = "green") {
13
13
  __privateAdd(this, _name);
14
14
  __privateAdd(this, _color);
15
15
  __privateAdd(this, _enabled, true);
16
16
  __privateSet(this, _name, name);
17
17
  __privateSet(this, _color, color);
18
- this.enable();
19
18
  }
20
- /**
21
- * 이름과 색상을 변경하고 다시 활성화
22
- */
23
- init(name, color = "#4CAF50") {
19
+ init(name, color = "green") {
24
20
  __privateSet(this, _name, name);
25
21
  __privateSet(this, _color, color);
26
- this.enable();
27
22
  }
28
- /**
29
- * 로그 기능을 활성화 (bind 실행)
30
- */
23
+ // 🔴 핵심: 함수를 갈아끼우지 않고, 호출될 때마다 상태를 체크합니다.
24
+ log(...args) {
25
+ if (!__privateGet(this, _enabled)) return;
26
+ const style = `color: ${__privateGet(this, _color)}; font-weight: bold;`;
27
+ console.log(`%c[${__privateGet(this, _name)}]`, style, ...args);
28
+ }
29
+ warn(...args) {
30
+ if (!__privateGet(this, _enabled)) return;
31
+ console.warn(`%c[${__privateGet(this, _name)}]`, "color: cyan; font-weight: bold;", ...args);
32
+ }
33
+ error(...args) {
34
+ if (!__privateGet(this, _enabled)) return;
35
+ console.error(`%c[${__privateGet(this, _name)}]`, "color: red; font-weight: bold;", ...args);
36
+ }
31
37
  enable() {
32
38
  __privateSet(this, _enabled, true);
33
- const style = `color: ${__privateGet(this, _color)}; font-weight: bold;`;
34
- this.log = console.log.bind(console, `%c[${__privateGet(this, _name)}]`, style);
35
- this.error = console.error.bind(console, `%c[${__privateGet(this, _name)}-ERR]`, "color: #ff4444; font-weight: bold;");
36
- this.warn = console.warn.bind(console, `%c[${__privateGet(this, _name)}-WARN]`, "color: #ffeb3b; font-weight: bold;");
37
39
  }
38
- /**
39
- * 로그 기능을 비활성화 (빈 함수로 대체)
40
- */
41
40
  disable() {
42
41
  __privateSet(this, _enabled, false);
43
- this.log = this.error = this.warn = () => {
44
- };
45
42
  }
46
43
  }
47
44
  _name = new WeakMap();
48
45
  _color = new WeakMap();
49
46
  _enabled = new WeakMap();
50
- const trace$1 = new Trace();
47
+ const trace = new Trace();
51
48
  if (typeof window !== "undefined") {
52
- window.trace = trace$1;
49
+ window.trace = trace;
53
50
  }
54
51
  class TaskDebouncer {
55
52
  constructor(delay = 50) {
@@ -88,7 +85,6 @@ flush_fn = function() {
88
85
  });
89
86
  __privateSet(this, _timer, null);
90
87
  };
91
- const trace = new Trace();
92
88
  export {
93
89
  TaskDebouncer,
94
90
  Trace,
@@ -1 +1 @@
1
- {"version":3,"file":"nine-util.js","sources":["../src/Trace.js","../src/TaskDebouncer.js","../src/index.js"],"sourcesContent":["export class Trace {\r\n\t#name;\r\n\t#color;\r\n\t#enabled = true; // 현재 상태 저장용\r\n\r\n\tconstructor(name = \"nine-util\", color = \"#4CAF50\") {\r\n\t\tthis.#name = name;\r\n\t\tthis.#color = color;\r\n\t\tthis.enable(); // 생성 시 기본 활성화\r\n\t}\r\n\r\n\t/**\r\n\t * 이름과 색상을 변경하고 다시 활성화\r\n\t */\r\n\tinit(name, color = \"#4CAF50\") {\r\n\t\tthis.#name = name;\r\n\t\tthis.#color = color;\r\n\t\tthis.enable();\r\n\t}\r\n\r\n\t/**\r\n\t * 로그 기능을 활성화 (bind 실행)\r\n\t */\r\n\tenable() {\r\n\t\tthis.#enabled = true;\r\n\t\tconst style = `color: ${this.#color}; font-weight: bold;`;\r\n\r\n\t\tthis.log = console.log.bind(console, `%c[${this.#name}]`, style);\r\n\t\tthis.error = console.error.bind(console, `%c[${this.#name}-ERR]`, \"color: #ff4444; font-weight: bold;\");\r\n\t\tthis.warn = console.warn.bind(console, `%c[${this.#name}-WARN]`, \"color: #ffeb3b; font-weight: bold;\");\r\n\t}\r\n\r\n\t/**\r\n\t * 로그 기능을 비활성화 (빈 함수로 대체)\r\n\t */\r\n\tdisable() {\r\n\t\tthis.#enabled = false;\r\n\t\tthis.log = this.error = this.warn = () => {};\r\n\t}\r\n}\r\n\r\nexport const trace = new Trace();\r\n\r\n// 브라우저 콘솔에서 즉시 제어할 수 있도록 window에 연결\r\nif (typeof window !== 'undefined') {\r\n\twindow.trace = trace;\r\n}","export class TaskDebouncer {\r\n\t#timer = null;\r\n\t#queue = [];\r\n\t#delay;\r\n\r\n\tconstructor(delay = 50) {\r\n\t\tthis.#delay = delay;\r\n\t}\r\n\r\n\t/**\r\n\t * @param {Function} func - 실행할 함수\r\n\t * @param {...any} args - 함수에 전달할 임의의 파라미터들\r\n\t */\r\n\texec(func, ...args) {\r\n\t\t// 1. 어떤 함수와 어떤 인자들이 들어왔는지 큐에 저장\r\n\t\tthis.#queue.push({ func, args });\r\n\r\n\t\t// 2. 디바운스 타이머 설정\r\n\t\tif (this.#timer) clearTimeout(this.#timer);\r\n\r\n\t\tthis.#timer = setTimeout(() => {\r\n\t\t\tthis.#flush();\r\n\t\t}, this.#delay);\r\n\t}\r\n\r\n\t#flush() {\r\n\t\tif (this.#queue.length === 0) return;\r\n\r\n\t\t// 3. 현재까지 쌓인 큐를 쏙 빼옴\r\n\t\tconst tasks = this.#queue.splice(0, this.#queue.length);\r\n\t\tconst seen = new Set();\r\n\r\n\t\ttasks.forEach(task => {\r\n\t\t\t// 4. 핵심: 함수 이름과 인자들을 문자열로 합쳐서 유니크 키 생성\r\n\t\t\t// JSON.stringify를 통해 [1, {a:1}] 같은 파라미터도 문자열로 비교 가능\r\n\t\t\tconst identifier = `${task.func.name}_${JSON.stringify(task.args)}`;\r\n\r\n\t\t\tif (!seen.has(identifier)) {\r\n\t\t\t\t// 5. 중복이 아닐 때만 원래 인자들(...args) 그대로 실행\r\n\t\t\t\ttask.func(...task.args);\r\n\t\t\t\tseen.add(identifier);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tthis.#timer = null;\r\n\t}\r\n}","import { Trace } from './Trace.js';\r\nimport { TaskDebouncer } from './TaskDebouncer.js';\r\n\r\n// 1. 기본 인스턴스를 내보내되, 이름은 'util' 같은 범용적인 값으로 설정\r\nconst trace = new Trace();\r\n\r\n// 2. 사용자가 원한다면 이름표를 바꿀 수 있는 기능 제공 (선택 사항)\r\n// trace.init(\"my-app\") 처럼 호출 가능하게 Trace 클래스에 메서드가 있다면 베스트!\r\n\r\nexport {\r\n\tTrace,\r\n\tTaskDebouncer,\r\n\ttrace // 미리 만든 인스턴스\r\n};"],"names":["trace"],"mappings":";;;;;;;;AAAO;AAAA,MAAM,MAAM;AAAA;AAAA,EAKlB,YAAY,OAAO,aAAa,QAAQ,WAAW;AAJnD;AACA;AACA,iCAAW;AAGV,uBAAK,OAAQ;AACb,uBAAK,QAAS;AACd,SAAK,OAAM;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK,MAAM,QAAQ,WAAW;AAC7B,uBAAK,OAAQ;AACb,uBAAK,QAAS;AACd,SAAK,OAAM;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS;AACR,uBAAK,UAAW;AAChB,UAAM,QAAQ,UAAU,mBAAK,OAAM;AAEnC,SAAK,MAAM,QAAQ,IAAI,KAAK,SAAS,MAAM,mBAAK,MAAK,KAAK,KAAK;AAC/D,SAAK,QAAQ,QAAQ,MAAM,KAAK,SAAS,MAAM,mBAAK,MAAK,SAAS,oCAAoC;AACtG,SAAK,OAAO,QAAQ,KAAK,KAAK,SAAS,MAAM,mBAAK,MAAK,UAAU,oCAAoC;AAAA,EACtG;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AACT,uBAAK,UAAW;AAChB,SAAK,MAAM,KAAK,QAAQ,KAAK,OAAO,MAAM;AAAA,IAAC;AAAA,EAC5C;AACD;AAtCC;AACA;AACA;AAsCM,MAAMA,UAAQ,IAAI;AAGzB,IAAI,OAAO,WAAW,aAAa;AAClC,SAAO,QAAQA;AAChB;AC9CO,MAAM,cAAc;AAAA,EAK1B,YAAY,QAAQ,IAAI;AALlB;AACN,+BAAS;AACT,+BAAS,CAAA;AACT;AAGC,uBAAK,QAAS;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,SAAS,MAAM;AAEnB,uBAAK,QAAO,KAAK,EAAE,MAAM,KAAI,CAAE;AAG/B,QAAI,mBAAK,QAAQ,cAAa,mBAAK,OAAM;AAEzC,uBAAK,QAAS,WAAW,MAAM;AAC9B,4BAAK,oCAAL;AAAA,IACD,GAAG,mBAAK,OAAM;AAAA,EACf;AAuBD;AA7CC;AACA;AACA;AAHM;AAyBN,WAAM,WAAG;AACR,MAAI,mBAAK,QAAO,WAAW,EAAG;AAG9B,QAAM,QAAQ,mBAAK,QAAO,OAAO,GAAG,mBAAK,QAAO,MAAM;AACtD,QAAM,OAAO,oBAAI;AAEjB,QAAM,QAAQ,UAAQ;AAGrB,UAAM,aAAa,GAAG,KAAK,KAAK,IAAI,IAAI,KAAK,UAAU,KAAK,IAAI,CAAC;AAEjE,QAAI,CAAC,KAAK,IAAI,UAAU,GAAG;AAE1B,WAAK,KAAK,GAAG,KAAK,IAAI;AACtB,WAAK,IAAI,UAAU;AAAA,IACpB;AAAA,EACD,CAAC;AAED,qBAAK,QAAS;AACf;ACzCI,MAAC,QAAQ,IAAI,MAAK;"}
1
+ {"version":3,"file":"nine-util.js","sources":["../src/Trace.js","../src/TaskDebouncer.js"],"sourcesContent":["export class Trace {\r\n\t#name;\r\n\t#color;\r\n\t#enabled = true; // 👈 상태값이 기준이 됩니다.\r\n\r\n\tconstructor(name = \"nine-util\", color = \"green\") {\r\n\t\tthis.#name = name;\r\n\t\tthis.#color = color;\r\n\t}\r\n\r\n\tinit(name, color = \"green\") {\r\n\t\tthis.#name = name;\r\n\t\tthis.#color = color;\r\n\t}\r\n\r\n\t// 🔴 핵심: 함수를 갈아끼우지 않고, 호출될 때마다 상태를 체크합니다.\r\n\tlog(...args) {\r\n\t\tif (!this.#enabled) return;\r\n\t\tconst style = `color: ${this.#color}; font-weight: bold;`;\r\n\t\tconsole.log(`%c[${this.#name}]`, style, ...args);\r\n\t}\r\n\r\n\twarn(...args) {\r\n\t\tif (!this.#enabled) return;\r\n\t\tconsole.warn(`%c[${this.#name}]`, \"color: cyan; font-weight: bold;\", ...args);\r\n\t}\r\n\r\n\terror(...args) {\r\n\t\tif (!this.#enabled) return;\r\n\t\tconsole.error(`%c[${this.#name}]`, \"color: red; font-weight: bold;\", ...args);\r\n\t}\r\n\r\n\tenable() { this.#enabled = true; }\r\n\tdisable() { this.#enabled = false; }\r\n}\r\n\r\nexport const trace = new Trace();\r\n\r\n// 브라우저 콘솔에서 즉시 제어할 수 있도록 window에 연결\r\nif (typeof window !== 'undefined') {\r\n\twindow.trace = trace;\r\n}","export class TaskDebouncer {\r\n\t#timer = null;\r\n\t#queue = [];\r\n\t#delay;\r\n\r\n\tconstructor(delay = 50) {\r\n\t\tthis.#delay = delay;\r\n\t}\r\n\r\n\t/**\r\n\t * @param {Function} func - 실행할 함수\r\n\t * @param {...any} args - 함수에 전달할 임의의 파라미터들\r\n\t */\r\n\texec(func, ...args) {\r\n\t\t// 1. 어떤 함수와 어떤 인자들이 들어왔는지 큐에 저장\r\n\t\tthis.#queue.push({ func, args });\r\n\r\n\t\t// 2. 디바운스 타이머 설정\r\n\t\tif (this.#timer) clearTimeout(this.#timer);\r\n\r\n\t\tthis.#timer = setTimeout(() => {\r\n\t\t\tthis.#flush();\r\n\t\t}, this.#delay);\r\n\t}\r\n\r\n\t#flush() {\r\n\t\tif (this.#queue.length === 0) return;\r\n\r\n\t\t// 3. 현재까지 쌓인 큐를 쏙 빼옴\r\n\t\tconst tasks = this.#queue.splice(0, this.#queue.length);\r\n\t\tconst seen = new Set();\r\n\r\n\t\ttasks.forEach(task => {\r\n\t\t\t// 4. 핵심: 함수 이름과 인자들을 문자열로 합쳐서 유니크 키 생성\r\n\t\t\t// JSON.stringify를 통해 [1, {a:1}] 같은 파라미터도 문자열로 비교 가능\r\n\t\t\tconst identifier = `${task.func.name}_${JSON.stringify(task.args)}`;\r\n\r\n\t\t\tif (!seen.has(identifier)) {\r\n\t\t\t\t// 5. 중복이 아닐 때만 원래 인자들(...args) 그대로 실행\r\n\t\t\t\ttask.func(...task.args);\r\n\t\t\t\tseen.add(identifier);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tthis.#timer = null;\r\n\t}\r\n}"],"names":[],"mappings":";;;;;;;;AAAO;AAAA,MAAM,MAAM;AAAA;AAAA,EAKlB,YAAY,OAAO,aAAa,QAAQ,SAAS;AAJjD;AACA;AACA,iCAAW;AAGV,uBAAK,OAAQ;AACb,uBAAK,QAAS;AAAA,EACf;AAAA,EAEA,KAAK,MAAM,QAAQ,SAAS;AAC3B,uBAAK,OAAQ;AACb,uBAAK,QAAS;AAAA,EACf;AAAA;AAAA,EAGA,OAAO,MAAM;AACZ,QAAI,CAAC,mBAAK,UAAU;AACpB,UAAM,QAAQ,UAAU,mBAAK,OAAM;AACnC,YAAQ,IAAI,MAAM,mBAAK,MAAK,KAAK,OAAO,GAAG,IAAI;AAAA,EAChD;AAAA,EAEA,QAAQ,MAAM;AACb,QAAI,CAAC,mBAAK,UAAU;AACpB,YAAQ,KAAK,MAAM,mBAAK,MAAK,KAAK,mCAAmC,GAAG,IAAI;AAAA,EAC7E;AAAA,EAEA,SAAS,MAAM;AACd,QAAI,CAAC,mBAAK,UAAU;AACpB,YAAQ,MAAM,MAAM,mBAAK,MAAK,KAAK,kCAAkC,GAAG,IAAI;AAAA,EAC7E;AAAA,EAEA,SAAS;AAAE,uBAAK,UAAW;AAAA,EAAM;AAAA,EACjC,UAAU;AAAE,uBAAK,UAAW;AAAA,EAAO;AACpC;AAjCC;AACA;AACA;AAiCW,MAAC,QAAQ,IAAI,MAAK;AAG9B,IAAI,OAAO,WAAW,aAAa;AAClC,SAAO,QAAQ;AAChB;ACzCO,MAAM,cAAc;AAAA,EAK1B,YAAY,QAAQ,IAAI;AALlB;AACN,+BAAS;AACT,+BAAS,CAAA;AACT;AAGC,uBAAK,QAAS;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,SAAS,MAAM;AAEnB,uBAAK,QAAO,KAAK,EAAE,MAAM,KAAI,CAAE;AAG/B,QAAI,mBAAK,QAAQ,cAAa,mBAAK,OAAM;AAEzC,uBAAK,QAAS,WAAW,MAAM;AAC9B,4BAAK,oCAAL;AAAA,IACD,GAAG,mBAAK,OAAM;AAAA,EACf;AAuBD;AA7CC;AACA;AACA;AAHM;AAyBN,WAAM,WAAG;AACR,MAAI,mBAAK,QAAO,WAAW,EAAG;AAG9B,QAAM,QAAQ,mBAAK,QAAO,OAAO,GAAG,mBAAK,QAAO,MAAM;AACtD,QAAM,OAAO,oBAAI;AAEjB,QAAM,QAAQ,UAAQ;AAGrB,UAAM,aAAa,GAAG,KAAK,KAAK,IAAI,IAAI,KAAK,UAAU,KAAK,IAAI,CAAC;AAEjE,QAAI,CAAC,KAAK,IAAI,UAAU,GAAG;AAE1B,WAAK,KAAK,GAAG,KAAK,IAAI;AACtB,WAAK,IAAI,UAAU;AAAA,IACpB;AAAA,EACD,CAAC;AAED,qBAAK,QAAS;AACf;"}
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).NineUtil={})}(this,function(e){"use strict";var t,i,s,n,o,a,h,r,c=e=>{throw TypeError(e)},l=(e,t,i)=>t.has(e)||c("Cannot "+i),f=(e,t,i)=>(l(e,t,"read from private field"),i?i.call(e):t.get(e)),d=(e,t,i)=>t.has(e)?c("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,i),u=(e,t,i,s)=>(l(e,t,"write to private field"),s?s.call(e,i):t.set(e,i),i);class p{constructor(e="nine-util",n="#4CAF50"){d(this,t),d(this,i),d(this,s,!0),u(this,t,e),u(this,i,n),this.enable()}init(e,s="#4CAF50"){u(this,t,e),u(this,i,s),this.enable()}enable(){u(this,s,!0);const e=`color: ${f(this,i)}; font-weight: bold;`;this.log=console.log.bind(console,`%c[${f(this,t)}]`,e),this.error=console.error.bind(console,`%c[${f(this,t)}-ERR]`,"color: #ff4444; font-weight: bold;"),this.warn=console.warn.bind(console,`%c[${f(this,t)}-WARN]`,"color: #ffeb3b; font-weight: bold;")}disable(){u(this,s,!1),this.log=this.error=this.warn=()=>{}}}t=new WeakMap,i=new WeakMap,s=new WeakMap;const w=new p;"undefined"!=typeof window&&(window.trace=w);n=new WeakMap,o=new WeakMap,a=new WeakMap,h=new WeakSet,r=function(){if(0===f(this,o).length)return;const e=f(this,o).splice(0,f(this,o).length),t=new Set;e.forEach(e=>{const i=`${e.func.name}_${JSON.stringify(e.args)}`;t.has(i)||(e.func(...e.args),t.add(i))}),u(this,n,null)};const b=new p;e.TaskDebouncer=class{constructor(e=50){d(this,h),d(this,n,null),d(this,o,[]),d(this,a),u(this,a,e)}exec(e,...t){f(this,o).push({func:e,args:t}),f(this,n)&&clearTimeout(f(this,n)),u(this,n,setTimeout(()=>{var e,t,i;(e=this,t=h,i=r,l(e,t,"access private method"),i).call(this)},f(this,a)))}},e.Trace=p,e.trace=b,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).NineUtil={})}(this,function(e){"use strict";var t,i,n,s,o,a,r,h,c=e=>{throw TypeError(e)},l=(e,t,i)=>t.has(e)||c("Cannot "+i),f=(e,t,i)=>(l(e,t,"read from private field"),i?i.call(e):t.get(e)),d=(e,t,i)=>t.has(e)?c("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,i),u=(e,t,i,n)=>(l(e,t,"write to private field"),n?n.call(e,i):t.set(e,i),i);class p{constructor(e="nine-util",s="green"){d(this,t),d(this,i),d(this,n,!0),u(this,t,e),u(this,i,s)}init(e,n="green"){u(this,t,e),u(this,i,n)}log(...e){if(!f(this,n))return;const s=`color: ${f(this,i)}; font-weight: bold;`;console.log(`%c[${f(this,t)}]`,s,...e)}warn(...e){f(this,n)&&console.warn(`%c[${f(this,t)}]`,"color: cyan; font-weight: bold;",...e)}error(...e){f(this,n)&&console.error(`%c[${f(this,t)}]`,"color: red; font-weight: bold;",...e)}enable(){u(this,n,!0)}disable(){u(this,n,!1)}}t=new WeakMap,i=new WeakMap,n=new WeakMap;const w=new p;"undefined"!=typeof window&&(window.trace=w);s=new WeakMap,o=new WeakMap,a=new WeakMap,r=new WeakSet,h=function(){if(0===f(this,o).length)return;const e=f(this,o).splice(0,f(this,o).length),t=new Set;e.forEach(e=>{const i=`${e.func.name}_${JSON.stringify(e.args)}`;t.has(i)||(e.func(...e.args),t.add(i))}),u(this,s,null)},e.TaskDebouncer=class{constructor(e=50){d(this,r),d(this,s,null),d(this,o,[]),d(this,a),u(this,a,e)}exec(e,...t){f(this,o).push({func:e,args:t}),f(this,s)&&clearTimeout(f(this,s)),u(this,s,setTimeout(()=>{var e,t,i;(e=this,t=r,i=h,l(e,t,"access private method"),i).call(this)},f(this,a)))}},e.Trace=p,e.trace=w,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});
2
2
  //# sourceMappingURL=nine-util.umd.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"nine-util.umd.cjs","sources":["../src/Trace.js","../src/TaskDebouncer.js","../src/index.js"],"sourcesContent":["export class Trace {\r\n\t#name;\r\n\t#color;\r\n\t#enabled = true; // 현재 상태 저장용\r\n\r\n\tconstructor(name = \"nine-util\", color = \"#4CAF50\") {\r\n\t\tthis.#name = name;\r\n\t\tthis.#color = color;\r\n\t\tthis.enable(); // 생성 시 기본 활성화\r\n\t}\r\n\r\n\t/**\r\n\t * 이름과 색상을 변경하고 다시 활성화\r\n\t */\r\n\tinit(name, color = \"#4CAF50\") {\r\n\t\tthis.#name = name;\r\n\t\tthis.#color = color;\r\n\t\tthis.enable();\r\n\t}\r\n\r\n\t/**\r\n\t * 로그 기능을 활성화 (bind 실행)\r\n\t */\r\n\tenable() {\r\n\t\tthis.#enabled = true;\r\n\t\tconst style = `color: ${this.#color}; font-weight: bold;`;\r\n\r\n\t\tthis.log = console.log.bind(console, `%c[${this.#name}]`, style);\r\n\t\tthis.error = console.error.bind(console, `%c[${this.#name}-ERR]`, \"color: #ff4444; font-weight: bold;\");\r\n\t\tthis.warn = console.warn.bind(console, `%c[${this.#name}-WARN]`, \"color: #ffeb3b; font-weight: bold;\");\r\n\t}\r\n\r\n\t/**\r\n\t * 로그 기능을 비활성화 (빈 함수로 대체)\r\n\t */\r\n\tdisable() {\r\n\t\tthis.#enabled = false;\r\n\t\tthis.log = this.error = this.warn = () => {};\r\n\t}\r\n}\r\n\r\nexport const trace = new Trace();\r\n\r\n// 브라우저 콘솔에서 즉시 제어할 수 있도록 window에 연결\r\nif (typeof window !== 'undefined') {\r\n\twindow.trace = trace;\r\n}","export class TaskDebouncer {\r\n\t#timer = null;\r\n\t#queue = [];\r\n\t#delay;\r\n\r\n\tconstructor(delay = 50) {\r\n\t\tthis.#delay = delay;\r\n\t}\r\n\r\n\t/**\r\n\t * @param {Function} func - 실행할 함수\r\n\t * @param {...any} args - 함수에 전달할 임의의 파라미터들\r\n\t */\r\n\texec(func, ...args) {\r\n\t\t// 1. 어떤 함수와 어떤 인자들이 들어왔는지 큐에 저장\r\n\t\tthis.#queue.push({ func, args });\r\n\r\n\t\t// 2. 디바운스 타이머 설정\r\n\t\tif (this.#timer) clearTimeout(this.#timer);\r\n\r\n\t\tthis.#timer = setTimeout(() => {\r\n\t\t\tthis.#flush();\r\n\t\t}, this.#delay);\r\n\t}\r\n\r\n\t#flush() {\r\n\t\tif (this.#queue.length === 0) return;\r\n\r\n\t\t// 3. 현재까지 쌓인 큐를 쏙 빼옴\r\n\t\tconst tasks = this.#queue.splice(0, this.#queue.length);\r\n\t\tconst seen = new Set();\r\n\r\n\t\ttasks.forEach(task => {\r\n\t\t\t// 4. 핵심: 함수 이름과 인자들을 문자열로 합쳐서 유니크 키 생성\r\n\t\t\t// JSON.stringify를 통해 [1, {a:1}] 같은 파라미터도 문자열로 비교 가능\r\n\t\t\tconst identifier = `${task.func.name}_${JSON.stringify(task.args)}`;\r\n\r\n\t\t\tif (!seen.has(identifier)) {\r\n\t\t\t\t// 5. 중복이 아닐 때만 원래 인자들(...args) 그대로 실행\r\n\t\t\t\ttask.func(...task.args);\r\n\t\t\t\tseen.add(identifier);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tthis.#timer = null;\r\n\t}\r\n}","import { Trace } from './Trace.js';\r\nimport { TaskDebouncer } from './TaskDebouncer.js';\r\n\r\n// 1. 기본 인스턴스를 내보내되, 이름은 'util' 같은 범용적인 값으로 설정\r\nconst trace = new Trace();\r\n\r\n// 2. 사용자가 원한다면 이름표를 바꿀 수 있는 기능 제공 (선택 사항)\r\n// trace.init(\"my-app\") 처럼 호출 가능하게 Trace 클래스에 메서드가 있다면 베스트!\r\n\r\nexport {\r\n\tTrace,\r\n\tTaskDebouncer,\r\n\ttrace // 미리 만든 인스턴스\r\n};"],"names":["Trace","constructor","name","color","__privateAdd","this","_name","_color","_enabled","__privateSet","enable","init","style","__privateGet","log","console","bind","error","warn","disable","WeakMap","trace","window","_timer","_queue","_delay","_TaskDebouncer_instances","WeakSet","flush_fn","length","tasks","splice","seen","Set","forEach","task","identifier","func","JSON","stringify","args","has","add","delay","exec","push","clearTimeout","setTimeout","call"],"mappings":"kkBAAO,MAAMA,EAKZ,WAAAC,CAAYC,EAAO,YAAaC,EAAQ,WAJxCC,EAAAC,KAAAC,GACAF,EAAAC,KAAAE,GACAH,EAAAC,KAAAG,GAAW,GAGVC,EAAAJ,KAAKC,EAAQJ,GACbO,EAAAJ,KAAKE,EAASJ,GACdE,KAAKK,QACN,CAKA,IAAAC,CAAKT,EAAMC,EAAQ,WAClBM,EAAAJ,KAAKC,EAAQJ,GACbO,EAAAJ,KAAKE,EAASJ,GACdE,KAAKK,QACN,CAKA,MAAAA,GACCD,EAAAJ,KAAKG,GAAW,GAChB,MAAMI,EAAQ,UAAUC,EAAAR,KAAKE,yBAE7BF,KAAKS,IAAMC,QAAQD,IAAIE,KAAKD,QAAS,MAAMF,EAAAR,KAAKC,MAAUM,GAC1DP,KAAKY,MAAQF,QAAQE,MAAMD,KAAKD,QAAS,MAAMF,EAAAR,KAAKC,UAAc,sCAClED,KAAKa,KAAOH,QAAQG,KAAKF,KAAKD,QAAS,MAAMF,EAAAR,KAAKC,WAAe,qCAClE,CAKA,OAAAa,GACCV,EAAAJ,KAAKG,GAAW,GAChBH,KAAKS,IAAMT,KAAKY,MAAQZ,KAAKa,KAAO,MACrC,EArCAZ,EAAA,IAAAc,QACAb,EAAA,IAAAa,QACAZ,EAAA,IAAAY,QAsCM,MAAMC,EAAQ,IAAIrB,EAGH,oBAAXsB,SACVA,OAAOD,MAAQA,GC5CfE,EAAA,IAAAH,QACAI,EAAA,IAAAJ,QACAK,EAAA,IAAAL,QAHMM,EAAA,IAAAC,QAyBNC,EAAM,WACL,GAA2B,IAAvBf,EAAAR,KAAKmB,GAAOK,OAAc,OAG9B,MAAMC,EAAQjB,EAAAR,KAAKmB,GAAOO,OAAO,EAAGlB,EAAAR,KAAKmB,GAAOK,QAC1CG,MAAWC,IAEjBH,EAAMI,QAAQC,IAGb,MAAMC,EAAa,GAAGD,EAAKE,KAAKnC,QAAQoC,KAAKC,UAAUJ,EAAKK,QAEvDR,EAAKS,IAAIL,KAEbD,EAAKE,QAAQF,EAAKK,MAClBR,EAAKU,IAAIN,MAIX3B,EAAAJ,KAAKkB,EAAS,KACf,ECzCI,MAACF,EAAQ,IAAIrB,kBDJX,MAKN,WAAAC,CAAY0C,EAAQ,IALdvC,EAAAC,KAAAqB,GACNtB,EAAAC,KAAAkB,EAAS,MACTnB,EAAAC,KAAAmB,EAAS,IACTpB,EAAAC,KAAAoB,GAGChB,EAAAJ,KAAKoB,EAASkB,EACf,CAMA,IAAAC,CAAKP,KAASG,GAEb3B,EAAAR,KAAKmB,GAAOqB,KAAK,CAAER,OAAMG,SAGrB3B,EAAAR,KAAKkB,IAAQuB,aAAajC,EAAAR,KAAKkB,IAEnCd,EAAAJ,KAAKkB,EAASwB,WAAW,kBACxB1C,OAAKqB,IAAAE,oCAALoB,KAAA3C,OACEQ,OAAKY,IACT"}
1
+ {"version":3,"file":"nine-util.umd.cjs","sources":["../src/Trace.js","../src/TaskDebouncer.js"],"sourcesContent":["export class Trace {\r\n\t#name;\r\n\t#color;\r\n\t#enabled = true; // 👈 상태값이 기준이 됩니다.\r\n\r\n\tconstructor(name = \"nine-util\", color = \"green\") {\r\n\t\tthis.#name = name;\r\n\t\tthis.#color = color;\r\n\t}\r\n\r\n\tinit(name, color = \"green\") {\r\n\t\tthis.#name = name;\r\n\t\tthis.#color = color;\r\n\t}\r\n\r\n\t// 🔴 핵심: 함수를 갈아끼우지 않고, 호출될 때마다 상태를 체크합니다.\r\n\tlog(...args) {\r\n\t\tif (!this.#enabled) return;\r\n\t\tconst style = `color: ${this.#color}; font-weight: bold;`;\r\n\t\tconsole.log(`%c[${this.#name}]`, style, ...args);\r\n\t}\r\n\r\n\twarn(...args) {\r\n\t\tif (!this.#enabled) return;\r\n\t\tconsole.warn(`%c[${this.#name}]`, \"color: cyan; font-weight: bold;\", ...args);\r\n\t}\r\n\r\n\terror(...args) {\r\n\t\tif (!this.#enabled) return;\r\n\t\tconsole.error(`%c[${this.#name}]`, \"color: red; font-weight: bold;\", ...args);\r\n\t}\r\n\r\n\tenable() { this.#enabled = true; }\r\n\tdisable() { this.#enabled = false; }\r\n}\r\n\r\nexport const trace = new Trace();\r\n\r\n// 브라우저 콘솔에서 즉시 제어할 수 있도록 window에 연결\r\nif (typeof window !== 'undefined') {\r\n\twindow.trace = trace;\r\n}","export class TaskDebouncer {\r\n\t#timer = null;\r\n\t#queue = [];\r\n\t#delay;\r\n\r\n\tconstructor(delay = 50) {\r\n\t\tthis.#delay = delay;\r\n\t}\r\n\r\n\t/**\r\n\t * @param {Function} func - 실행할 함수\r\n\t * @param {...any} args - 함수에 전달할 임의의 파라미터들\r\n\t */\r\n\texec(func, ...args) {\r\n\t\t// 1. 어떤 함수와 어떤 인자들이 들어왔는지 큐에 저장\r\n\t\tthis.#queue.push({ func, args });\r\n\r\n\t\t// 2. 디바운스 타이머 설정\r\n\t\tif (this.#timer) clearTimeout(this.#timer);\r\n\r\n\t\tthis.#timer = setTimeout(() => {\r\n\t\t\tthis.#flush();\r\n\t\t}, this.#delay);\r\n\t}\r\n\r\n\t#flush() {\r\n\t\tif (this.#queue.length === 0) return;\r\n\r\n\t\t// 3. 현재까지 쌓인 큐를 쏙 빼옴\r\n\t\tconst tasks = this.#queue.splice(0, this.#queue.length);\r\n\t\tconst seen = new Set();\r\n\r\n\t\ttasks.forEach(task => {\r\n\t\t\t// 4. 핵심: 함수 이름과 인자들을 문자열로 합쳐서 유니크 키 생성\r\n\t\t\t// JSON.stringify를 통해 [1, {a:1}] 같은 파라미터도 문자열로 비교 가능\r\n\t\t\tconst identifier = `${task.func.name}_${JSON.stringify(task.args)}`;\r\n\r\n\t\t\tif (!seen.has(identifier)) {\r\n\t\t\t\t// 5. 중복이 아닐 때만 원래 인자들(...args) 그대로 실행\r\n\t\t\t\ttask.func(...task.args);\r\n\t\t\t\tseen.add(identifier);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tthis.#timer = null;\r\n\t}\r\n}"],"names":["Trace","constructor","name","color","__privateAdd","this","_name","_color","_enabled","__privateSet","init","log","args","__privateGet","style","console","warn","error","enable","disable","WeakMap","trace","window","_timer","_queue","_delay","_TaskDebouncer_instances","WeakSet","flush_fn","length","tasks","splice","seen","Set","forEach","task","identifier","func","JSON","stringify","has","add","delay","exec","push","clearTimeout","setTimeout","call"],"mappings":"kkBAAO,MAAMA,EAKZ,WAAAC,CAAYC,EAAO,YAAaC,EAAQ,SAJxCC,EAAAC,KAAAC,GACAF,EAAAC,KAAAE,GACAH,EAAAC,KAAAG,GAAW,GAGVC,EAAAJ,KAAKC,EAAQJ,GACbO,EAAAJ,KAAKE,EAASJ,EACf,CAEA,IAAAO,CAAKR,EAAMC,EAAQ,SAClBM,EAAAJ,KAAKC,EAAQJ,GACbO,EAAAJ,KAAKE,EAASJ,EACf,CAGA,GAAAQ,IAAOC,GACN,IAAKC,OAAKL,GAAU,OACpB,MAAMM,EAAQ,UAAUD,EAAAR,KAAKE,yBAC7BQ,QAAQJ,IAAI,MAAME,EAAAR,KAAKC,MAAUQ,KAAUF,EAC5C,CAEA,IAAAI,IAAQJ,GACFC,OAAKL,IACVO,QAAQC,KAAK,MAAMH,EAAAR,KAAKC,MAAU,qCAAsCM,EACzE,CAEA,KAAAK,IAASL,GACHC,OAAKL,IACVO,QAAQE,MAAM,MAAMJ,EAAAR,KAAKC,MAAU,oCAAqCM,EACzE,CAEA,MAAAM,GAAWT,EAAAJ,KAAKG,GAAW,EAAM,CACjC,OAAAW,GAAYV,EAAAJ,KAAKG,GAAW,EAAO,EAhCnCF,EAAA,IAAAc,QACAb,EAAA,IAAAa,QACAZ,EAAA,IAAAY,QAiCW,MAACC,EAAQ,IAAIrB,EAGH,oBAAXsB,SACVA,OAAOD,MAAQA,GCvCfE,EAAA,IAAAH,QACAI,EAAA,IAAAJ,QACAK,EAAA,IAAAL,QAHMM,EAAA,IAAAC,QAyBNC,EAAM,WACL,GAA2B,IAAvBf,EAAAR,KAAKmB,GAAOK,OAAc,OAG9B,MAAMC,EAAQjB,EAAAR,KAAKmB,GAAOO,OAAO,EAAGlB,EAAAR,KAAKmB,GAAOK,QAC1CG,MAAWC,IAEjBH,EAAMI,QAAQC,IAGb,MAAMC,EAAa,GAAGD,EAAKE,KAAKnC,QAAQoC,KAAKC,UAAUJ,EAAKvB,QAEvDoB,EAAKQ,IAAIJ,KAEbD,EAAKE,QAAQF,EAAKvB,MAClBoB,EAAKS,IAAIL,MAIX3B,EAAAJ,KAAKkB,EAAS,KACf,kBA7CM,MAKN,WAAAtB,CAAYyC,EAAQ,IALdtC,EAAAC,KAAAqB,GACNtB,EAAAC,KAAAkB,EAAS,MACTnB,EAAAC,KAAAmB,EAAS,IACTpB,EAAAC,KAAAoB,GAGChB,EAAAJ,KAAKoB,EAASiB,EACf,CAMA,IAAAC,CAAKN,KAASzB,GAEbC,EAAAR,KAAKmB,GAAOoB,KAAK,CAAEP,OAAMzB,SAGrBC,EAAAR,KAAKkB,IAAQsB,aAAahC,EAAAR,KAAKkB,IAEnCd,EAAAJ,KAAKkB,EAASuB,WAAW,kBACxBzC,OAAKqB,IAAAE,oCAALmB,KAAA1C,OACEQ,OAAKY,IACT"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nine-lab/nine-util",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Custom Element based Util Component for Real-time Collaboration",
5
5
  "type": "module",
6
6
  "main": "./dist/nine-util.umd.cjs",