@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 +35 -32
- package/dist/index.js +24 -10
- package/dist/index.min.js +1 -1
- package/package.json +1 -1
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
|
|
104
|
-
/**
|
|
105
|
-
|
|
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,
|
|
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>[
|
|
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
|
|
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> ?
|
|
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
|
-
/**
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
148
|
+
//@ts-expect-error impl generic show
|
|
138
149
|
show = this.#show;
|
|
139
|
-
/**
|
|
150
|
+
/**
|
|
151
|
+
* If called in frame, close in current frame (as microtask), else in next
|
|
152
|
+
* frame
|
|
153
|
+
*/
|
|
140
154
|
close() {
|
|
141
|
-
const
|
|
142
|
-
(currentFrameTime ? queueMicrotask : rAF)(() =>
|
|
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
|
|
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};
|