@psytask/core 1.1.3 → 1.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/dist/index.d.ts CHANGED
@@ -124,11 +124,15 @@ 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
+ declare const ReactiveFn: unique symbol;
128
+ type ComponentFlags = {
129
+ [ReactiveFn]?: <T extends LooseObject>(obj: T) => T;
130
+ };
127
131
  type ComponentAdapter = {
128
- /** Wrap a component with reactive props */
129
- wrap: <T extends Component>(component: T) => T;
130
- /** Render a component with default props and provided scene */
131
- render: <T extends Component>(component: T, defaultProps: Parameters<T>[0],
132
+ /** Mark a component with reactive function */
133
+ mark: <T extends Component>(component: T & ComponentFlags) => T;
134
+ /** Call a component with default props and provided scene */
135
+ render: <T extends Component>(component: T & ComponentFlags, defaultProps: Parameters<T>[0],
132
136
  /** If not provided, it will use current scene */
133
137
  ctx?: Scene<Component>) => {
134
138
  props: Parameters<T>[0];
@@ -143,6 +147,24 @@ type ComponentAdapter = {
143
147
  data: undefined;
144
148
  } : never);
145
149
  };
150
+ /**
151
+ * Adapte third-part reactive systems
152
+ *
153
+ * @example
154
+ *
155
+ * With Vue
156
+ *
157
+ * ```ts
158
+ * import { shallowReactive, effect } from '@vue/reactivity';
159
+ * const adapter = createComponentAdapter(shallowReactive);
160
+ * const VueComponent = (props: { text: string }) => {
161
+ * const node = document.createElement('div');
162
+ * effect(() => (node.textContent = props.text));
163
+ * return node;
164
+ * };
165
+ * const Component = adapter.mark(VueComponent);
166
+ * ```
167
+ */
146
168
  declare const createComponentAdapter: (reactive: <T extends LooseObject>(obj: T) => T) => ComponentAdapter;
147
169
  /**
148
170
  * Lifecycle hooks.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @psytask/core v1.1.3 cubxx MIT */
1
+ /** @psytask/core v1.2.0 cubxx MIT */
2
2
  const symbol = Symbol.dispose ?? /* @__PURE__ */ Symbol.for("Symbol.dispose");
3
3
  class EventEmitter {
4
4
  listeners = {};
@@ -15,19 +15,13 @@ class EventEmitter {
15
15
  const listeners = this.listeners[type];
16
16
  if (listeners) {
17
17
  listeners.delete(listener);
18
- listeners.size === 0 && delete this.listeners[type];
18
+ listeners.size || delete this.listeners[type];
19
19
  }
20
20
  return this;
21
21
  }
22
22
  /** Add one-time event listener, can not be removed manually */
23
23
  once(type, listener) {
24
- const wrapper = (evt) => {
25
- try {
26
- listener(evt);
27
- } finally {
28
- this.off(type, wrapper);
29
- }
30
- };
24
+ const wrapper = (evt) => (this.off(type, wrapper), listener(evt));
31
25
  this.on(type, wrapper);
32
26
  return this;
33
27
  }
@@ -84,18 +78,22 @@ const generic = (f) => (
84
78
  //@ts-expect-error impl generic component
85
79
  f
86
80
  );
81
+ const ReactiveFn = /* @__PURE__ */ Symbol();
87
82
  const createComponentAdapter = (reactive) => ({
88
- wrap: (component) => ((props) => component(reactive(props))),
89
- render: (component, defaultProps, ctx) => {
90
- const props = reactive(defaultProps);
83
+ mark(component) {
84
+ component[ReactiveFn] = reactive;
85
+ return component;
86
+ },
87
+ render(component, defaultProps, ctx) {
88
+ const rprops = (component[ReactiveFn] ?? reactive)(defaultProps);
91
89
  ctx && sceneStack.push(ctx);
92
- const instanceOrNode = component(props);
90
+ const instanceOrNode = component(rprops);
93
91
  ctx && sceneStack.pop();
94
92
  let data;
95
93
  const nodes = array_normalize(
96
94
  typeof instanceOrNode !== "string" && "node" in instanceOrNode ? (data = instanceOrNode.data, instanceOrNode.node) : instanceOrNode
97
95
  );
98
- return { props, nodes, data };
96
+ return { props: rprops, nodes, data };
99
97
  }
100
98
  });
101
99
  const sceneStack = [];
package/dist/index.min.js CHANGED
@@ -1 +1 @@
1
- const f=Symbol.dispose??Symbol.for("Symbol.dispose");class p{listeners={};[f](){this.emit("dispose")}on(t,s){return(this.listeners[t]??=new Set).add(s),this}off(t,s){const e=this.listeners[t];return e&&(e.delete(s),e.size===0&&delete this.listeners[t]),this}once(t,s){const e=r=>{try{s(r)}finally{this.off(t,e)}};return this.on(t,e),this}emit(t,...[s]){const e=this.listeners[t];if(e)for(const r of[...e])r(s);return this}}const y=o=>{throw Error(o)},d=requestAnimationFrame,w=Object,b=(o,t)=>w.assign(o,t),S=document;new Proxy({},{get:(o,t)=>s=>b(S.createElement(t),s)});const g=o=>Array.isArray(o)?o:[o];let c;const m=o=>(c=o,setTimeout(()=>c=0),d(m)),A=o=>{c??m(0);const t={start:s=>new Promise(e=>{const r=[];c&&(r.push(c),s?.(c));const n=a=>{const h=o(a,r);r.push(a),h?t.stop():(s?.(a),i=d(n))};let i=d(n);t.stop=()=>{r.pop(),cancelAnimationFrame(i),e(r)}}),stop(){}};return t},E=o=>o,F=o=>({wrap:t=>(s=>t(o(s))),render:(t,s,e)=>{const r=o(s);e&&l.push(e);const n=t(r);e&&l.pop();let i;const a=g(typeof n!="string"&&"node"in n?(i=n.data,n.node):n);return{props:r,nodes:a,data:i}}}),l=[],P=()=>l[l.length-1]??y("Not found current scene");class k extends p{constructor(t,s){super(),this.options=s;const{root:e,adapter:r,defaultProps:n,timer:i}=s;(this.root=e).tabIndex=-1,e.style.scale="0";const{props:a,nodes:h,data:u}=r.render(t,{...n},this.on("dispose",()=>e.remove()));this.#t=i(),this.#s=a,this.data=u,e.append(...h)}root;#t;#s;data;show=this.#e;close(){const t=this.#t;(c?queueMicrotask:d)(()=>t.stop())}async#e(t){const{root:s,defaultProps:e}=this.options,r={...e,...t};for(const i of Object.keys({...this.#s,...r}))this.#s[i]=r[i];this.emit("show"),s.style.scale="1",s.focus();const n=await this.#t.start(i=>this.emit("frame",i));return s.style.scale="0",{...this.emit("close").data?.(),frame_times:n,duration:c-n[0]}}}export{p as EventEmitter,k as Scene,F as createComponentAdapter,A as createTimer,E 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 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};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@psytask/core",
3
- "version": "1.1.3",
3
+ "version": "1.2.0",
4
4
  "type": "module",
5
5
  "author": "cubxx",
6
6
  "license": "MIT",