@psytask/core 1.2.0 → 1.2.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/dist/index.d.ts CHANGED
@@ -100,9 +100,9 @@ type Component<P extends LooseObject = any, D extends LooseObject = LooseObject
100
100
  data: () => D;
101
101
  };
102
102
  };
103
- type SceneShow<P extends LooseObject = LooseObject, D extends LooseObject = LooseObject & ForbiddenData> = (patchProps?: Partial<P>) => Promise<Merge<D, BuiltinData>>;
104
- /** Same with {@link SceneShow} */
105
- type GenericComponent<P extends LooseObject = LooseObject, D extends LooseObject = LooseObject & ForbiddenData> = SceneShow<P, D>;
103
+ type GenericComponent<P extends LooseObject = LooseObject, D extends LooseObject = LooseObject & ForbiddenData> = (patchProps?: Partial<P>,
104
+ /** NOTE: only for type hint */
105
+ __rawProps?: P) => Promise<Merge<D, BuiltinData>>;
106
106
  /**
107
107
  * Provide type infer for generic component, do nothing in runtime.
108
108
  *
@@ -124,6 +124,30 @@ declare const generic: {
124
124
  };
125
125
  /** @ignore */
126
126
  type MaybeGenericComponent<P extends LooseObject = any, D extends LooseObject & ForbiddenData = {}> = Component<P, D> | GenericComponent<P, D>;
127
+ /**
128
+ * @example
129
+ *
130
+ * Must be called on the top scope of component
131
+ *
132
+ * ```ts
133
+ * const Component = (props: {}) => {
134
+ * const ctx = getCurrentScene();
135
+ * return '';
136
+ * };
137
+ * ```
138
+ *
139
+ * DO NOT call on other place
140
+ *
141
+ * ```ts
142
+ * const Component = (props: {}) => {
143
+ * const fn = () => {
144
+ * const ctx = getCurrentScene(); // WRONG!
145
+ * };
146
+ * return '';
147
+ * };
148
+ * ```
149
+ */
150
+ declare const getCurrentScene: () => Scene<MaybeGenericComponent<any, {}>>;
127
151
  declare const ReactiveFn: unique symbol;
128
152
  type ComponentFlags = {
129
153
  [ReactiveFn]?: <T extends LooseObject>(obj: T) => T;
@@ -133,7 +157,7 @@ type ComponentAdapter = {
133
157
  mark: <T extends Component>(component: T & ComponentFlags) => T;
134
158
  /** Call a component with default props and provided scene */
135
159
  render: <T extends Component>(component: T & ComponentFlags, defaultProps: Parameters<T>[0],
136
- /** If not provided, it will use current scene */
160
+ /** If not provided, use current scene */
137
161
  ctx?: Scene<Component>) => {
138
162
  props: Parameters<T>[0];
139
163
  } & (ReturnType<T> extends infer R ? R extends {
@@ -180,36 +204,12 @@ type SceneEventMap = {
180
204
  frame: number;
181
205
  close: undefined;
182
206
  };
183
- /**
184
- * @example
185
- *
186
- * Must be called on the top scope of component
187
- *
188
- * ```ts
189
- * const Component = (props: {}) => {
190
- * const ctx = getCurrentScene();
191
- * return '';
192
- * };
193
- * ```
194
- *
195
- * DO NOT call on other place
196
- *
197
- * ```ts
198
- * const Component = (props: {}) => {
199
- * const fn = () => {
200
- * const ctx = getCurrentScene(); // WRONG!
201
- * };
202
- * return '';
203
- * };
204
- * ```
205
- */
206
- declare const getCurrentScene: () => Scene<MaybeGenericComponent<any, {}>>;
207
207
  /** Scene options */
208
208
  type SceneOptions<T extends MaybeGenericComponent> = {
209
209
  /** Root element */
210
210
  root: HTMLDivElement;
211
211
  /** Default props */
212
- defaultProps: Parameters<T>[0];
212
+ defaultProps: T extends Component<infer P, infer _> ? P : Parameters<T>[1] & {};
213
213
  /** Control show timing */
214
214
  timer: () => Timer;
215
215
  /** Component adapter */
@@ -219,7 +219,7 @@ declare class Scene<T extends MaybeGenericComponent> extends EventEmitter<SceneE
219
219
  #private;
220
220
  readonly options: SceneOptions<T>;
221
221
  readonly root: HTMLDivElement;
222
- readonly data: T extends MaybeGenericComponent<infer P, infer D> ? () => D : undefined;
222
+ readonly data: T extends MaybeGenericComponent<infer _, infer D> ? () => D : undefined;
223
223
  /**
224
224
  * Show DOM and update props one-time
225
225
  *
@@ -232,13 +232,16 @@ declare class Scene<T extends MaybeGenericComponent> extends EventEmitter<SceneE
232
232
  * await scene.show(); // show with default props
233
233
  * ```
234
234
  */
235
- show: T extends Component<infer P, infer D> ? SceneShow<P, D> : T;
235
+ show: T extends Component<infer P, infer D> ? (patchProps?: Partial<P>) => Promise<Merge<D, BuiltinData>> : T;
236
236
  /**
237
237
  * @param component - {@link Component}
238
238
  * @param options - {@link SceneOptions}
239
239
  */
240
240
  constructor(component: T, options: SceneOptions<T>);
241
- /** Add close task as Microtask if is caled in the frame else next rAF. */
241
+ /**
242
+ * If called in frame, close in current frame (as microtask), else in next
243
+ * frame
244
+ */
242
245
  close(): void;
243
246
  }
244
247
 
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @psytask/core v1.2.0 cubxx MIT */
1
+ /** @psytask/core v1.2.1 cubxx MIT */
2
2
  const symbol = Symbol.dispose ?? /* @__PURE__ */ Symbol.for("Symbol.dispose");
3
3
  class EventEmitter {
4
4
  listeners = {};
@@ -56,11 +56,19 @@ const createTimer = (shouldStop) => {
56
56
  const timer = {
57
57
  start: (cb) => new Promise((resolve) => {
58
58
  const records = [];
59
- currentFrameTime && (records.push(currentFrameTime), cb?.(currentFrameTime));
59
+ if (currentFrameTime) {
60
+ records.push(currentFrameTime);
61
+ cb?.(currentFrameTime);
62
+ }
60
63
  const frame = (time) => {
61
64
  const is_stoped = shouldStop(time, records);
62
65
  records.push(time);
63
- is_stoped ? timer.stop() : (cb?.(time), handle = rAF(frame));
66
+ if (is_stoped) {
67
+ timer.stop();
68
+ } else {
69
+ handle = rAF(frame);
70
+ cb?.(time);
71
+ }
64
72
  };
65
73
  let handle = rAF(frame);
66
74
  timer.stop = () => {
@@ -78,6 +86,8 @@ const generic = (f) => (
78
86
  //@ts-expect-error impl generic component
79
87
  f
80
88
  );
89
+ const sceneStack = [];
90
+ const getCurrentScene = () => sceneStack[sceneStack.length - 1] ?? ERR("Not found current scene");
81
91
  const ReactiveFn = /* @__PURE__ */ Symbol();
82
92
  const createComponentAdapter = (reactive) => ({
83
93
  mark(component) {
@@ -96,9 +106,8 @@ const createComponentAdapter = (reactive) => ({
96
106
  return { props: rprops, nodes, data };
97
107
  }
98
108
  });
99
- const sceneStack = [];
100
- const getCurrentScene = () => sceneStack[sceneStack.length - 1] ?? ERR("Not found current scene");
101
109
  class Scene extends EventEmitter {
110
+ // use GenericComponent as Scene.show type
102
111
  /**
103
112
  * @param component - {@link Component}
104
113
  * @param options - {@link SceneOptions}
@@ -110,12 +119,14 @@ class Scene extends EventEmitter {
110
119
  (this.root = root).tabIndex = -1;
111
120
  root.style.scale = "0";
112
121
  const { props, nodes, data } = adapter.render(
122
+ //@ts-expect-error impl generic component
113
123
  component,
114
124
  { ...defaultProps },
115
125
  this.on("dispose", () => root.remove())
116
126
  );
117
127
  this.#timer = timer();
118
- this.#props = props, this.data = data;
128
+ this.#props = props;
129
+ this.data = data;
119
130
  root.append(...nodes);
120
131
  }
121
132
  root;
@@ -134,12 +145,15 @@ class Scene extends EventEmitter {
134
145
  * await scene.show(); // show with default props
135
146
  * ```
136
147
  */
137
- //@ts-expect-error impl generic component
148
+ //@ts-expect-error impl generic show
138
149
  show = this.#show;
139
- /** Add close task as Microtask if is caled in the frame else next rAF. */
150
+ /**
151
+ * If called in frame, close in current frame (as microtask), else in next
152
+ * frame
153
+ */
140
154
  close() {
141
- const t = this.#timer;
142
- (currentFrameTime ? queueMicrotask : rAF)(() => t.stop());
155
+ const ref = this.#timer;
156
+ (currentFrameTime ? queueMicrotask : rAF)(() => ref.stop());
143
157
  }
144
158
  async #show(patchProps) {
145
159
  const { root, defaultProps } = this.options;
package/dist/index.min.js CHANGED
@@ -1 +1 @@
1
- const y=Symbol.dispose??Symbol.for("Symbol.dispose");class p{listeners={};[y](){this.emit("dispose")}on(t,e){return(this.listeners[t]??=new Set).add(e),this}off(t,e){const s=this.listeners[t];return s&&(s.delete(e),s.size||delete this.listeners[t]),this}once(t,e){const s=r=>(this.off(t,s),e(r));return this.on(t,s),this}emit(t,...[e]){const s=this.listeners[t];if(s)for(const r of[...s])r(e);return this}}const w=o=>{throw Error(o)},d=requestAnimationFrame,b=Object,S=(o,t)=>b.assign(o,t),g=document;new Proxy({},{get:(o,t)=>e=>S(g.createElement(t),e)});const A=o=>Array.isArray(o)?o:[o];let c;const m=o=>(c=o,setTimeout(()=>c=0),d(m)),F=o=>{c??m(0);const t={start:e=>new Promise(s=>{const r=[];c&&(r.push(c),e?.(c));const n=a=>{const l=o(a,r);r.push(a),l?t.stop():(e?.(a),i=d(n))};let i=d(n);t.stop=()=>{r.pop(),cancelAnimationFrame(i),s(r)}}),stop(){}};return t},k=o=>o,u=Symbol(),E=o=>({mark(t){return t[u]=o,t},render(t,e,s){const r=(t[u]??o)(e);s&&h.push(s);const n=t(r);s&&h.pop();let i;const a=A(typeof n!="string"&&"node"in n?(i=n.data,n.node):n);return{props:r,nodes:a,data:i}}}),h=[],P=()=>h[h.length-1]??w("Not found current scene");class O extends p{constructor(t,e){super(),this.options=e;const{root:s,adapter:r,defaultProps:n,timer:i}=e;(this.root=s).tabIndex=-1,s.style.scale="0";const{props:a,nodes:l,data:f}=r.render(t,{...n},this.on("dispose",()=>s.remove()));this.#t=i(),this.#s=a,this.data=f,s.append(...l)}root;#t;#s;data;show=this.#e;close(){const t=this.#t;(c?queueMicrotask:d)(()=>t.stop())}async#e(t){const{root:e,defaultProps:s}=this.options,r={...s,...t};for(const i of Object.keys({...this.#s,...r}))this.#s[i]=r[i];this.emit("show"),e.style.scale="1",e.focus();const n=await this.#t.start(i=>this.emit("frame",i));return e.style.scale="0",{...this.emit("close").data?.(),frame_times:n,duration:c-n[0]}}}export{p as EventEmitter,O as Scene,E as createComponentAdapter,F as createTimer,k as generic,P as getCurrentScene};
1
+ const y=Symbol.dispose??Symbol.for("Symbol.dispose");class p{listeners={};[y](){this.emit("dispose")}on(t,e){return(this.listeners[t]??=new Set).add(e),this}off(t,e){const s=this.listeners[t];return s&&(s.delete(e),s.size||delete this.listeners[t]),this}once(t,e){const s=r=>(this.off(t,s),e(r));return this.on(t,s),this}emit(t,...[e]){const s=this.listeners[t];if(s)for(const r of[...s])r(e);return this}}const w=o=>{throw Error(o)},d=requestAnimationFrame,b=Object,S=(o,t)=>b.assign(o,t),g=document;new Proxy({},{get:(o,t)=>e=>S(g.createElement(t),e)});const A=o=>Array.isArray(o)?o:[o];let c;const m=o=>(c=o,setTimeout(()=>c=0),d(m)),F=o=>{c??m(0);const t={start:e=>new Promise(s=>{const r=[];c&&(r.push(c),e?.(c));const n=a=>{const h=o(a,r);r.push(a),h?t.stop():(i=d(n),e?.(a))};let i=d(n);t.stop=()=>{r.pop(),cancelAnimationFrame(i),s(r)}}),stop(){}};return t},k=o=>o,l=[],E=()=>l[l.length-1]??w("Not found current scene"),u=Symbol(),P=o=>({mark(t){return t[u]=o,t},render(t,e,s){const r=(t[u]??o)(e);s&&l.push(s);const n=t(r);s&&l.pop();let i;const a=A(typeof n!="string"&&"node"in n?(i=n.data,n.node):n);return{props:r,nodes:a,data:i}}});class O extends p{constructor(t,e){super(),this.options=e;const{root:s,adapter:r,defaultProps:n,timer:i}=e;(this.root=s).tabIndex=-1,s.style.scale="0";const{props:a,nodes:h,data:f}=r.render(t,{...n},this.on("dispose",()=>s.remove()));this.#t=i(),this.#s=a,this.data=f,s.append(...h)}root;#t;#s;data;show=this.#e;close(){const t=this.#t;(c?queueMicrotask:d)(()=>t.stop())}async#e(t){const{root:e,defaultProps:s}=this.options,r={...s,...t};for(const i of Object.keys({...this.#s,...r}))this.#s[i]=r[i];this.emit("show"),e.style.scale="1",e.focus();const n=await this.#t.start(i=>this.emit("frame",i));return e.style.scale="0",{...this.emit("close").data?.(),frame_times:n,duration:c-n[0]}}}export{p as EventEmitter,O as Scene,P as createComponentAdapter,F as createTimer,k as generic,E as getCurrentScene};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@psytask/core",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "type": "module",
5
5
  "author": "cubxx",
6
6
  "license": "MIT",