From cf97cdcc9164ecff20d43345df1d0ef2d4d90ba3 Mon Sep 17 00:00:00 2001 From: Tao Xin Date: Sun, 7 Jul 2024 13:39:15 -0700 Subject: [PATCH] 0.5.7: Implement `rawVal` for state objects, fixes #11. --- README.md | 10 ++-- package-lock.json | 4 +- package.json | 2 +- public/mini-van-0.5.7.d.ts | 75 ++++++++++++++++++++++++++ public/mini-van-0.5.7.js | 48 +++++++++++++++++ public/mini-van-0.5.7.min.d.ts | 75 ++++++++++++++++++++++++++ public/mini-van-0.5.7.min.js | 1 + public/mini-van-0.5.7.nomodule.js | 45 ++++++++++++++++ public/mini-van-0.5.7.nomodule.min.js | 1 + public/mini-van-latest.d.ts | 1 + public/mini-van-latest.js | 3 +- public/mini-van-latest.min.d.ts | 1 + public/mini-van-latest.min.js | 2 +- public/mini-van-latest.nomodule.js | 2 + public/mini-van-latest.nomodule.min.js | 2 +- public/mini-van.version | 2 +- src/mini-van.d.ts | 1 + src/mini-van.js | 3 +- src/shared.d.ts | 1 + src/shared.ts | 1 + src/van-plate.d.ts | 1 + src/van-plate.js | 2 +- test/deno/van-plate.test.ts | 4 +- test/mini-van.test.js | 4 +- test/mini-van.test.nomodule.js | 4 +- test/mini-van.test.ts | 4 +- 26 files changed, 277 insertions(+), 22 deletions(-) create mode 100644 public/mini-van-0.5.7.d.ts create mode 100644 public/mini-van-0.5.7.js create mode 100644 public/mini-van-0.5.7.min.d.ts create mode 100644 public/mini-van-0.5.7.min.js create mode 100644 public/mini-van-0.5.7.nomodule.js create mode 100644 public/mini-van-0.5.7.nomodule.min.js diff --git a/README.md b/README.md index 07e757a..66abd72 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,7 @@ Sample code: _Requires Deno `1.35` or later._ ```typescript -import van from "https://deno.land/x/minivan@0.5.6/src/van-plate.js" +import van from "https://deno.land/x/minivan@0.5.7/src/van-plate.js" const {a, body, li, p, ul} = van.tags @@ -195,7 +195,7 @@ _Requires Deno `1.35` or later._ ```typescript import { DOMParser } from "https://deno.land/x/deno_dom@v0.1.38/deno-dom-wasm.ts" -import van from "https://deno.land/x/minivan@0.5.6/src/mini-van.js" +import van from "https://deno.land/x/minivan@0.5.7/src/mini-van.js" const document = new DOMParser().parseFromString("", "text/html")! const {tags, html} = van.vanWithDoc(document) @@ -235,16 +235,16 @@ Preview via [CodeSandbox](https://codesandbox.io/p/sandbox/github/vanjs-org/vanj To get started on the client side, add the line below to your script: ```javascript -import van from "https://cdn.jsdelivr.net/gh/vanjs-org/mini-van/public/mini-van-0.5.6.min.js" +import van from "https://cdn.jsdelivr.net/gh/vanjs-org/mini-van/public/mini-van-0.5.7.min.js" ``` To code without ES6 modules, add the following line to your HTML file instead: ```html - + ``` -Alternative, you can download the files ([`mini-van-0.5.6.min.js`](https://vanjs.org/autodownload?file=mini-van-0.5.6.min.js), [`mini-van-0.5.6.nomodule.min.js`](https://vanjs.org/autodownload?file=mini-van-0.5.6.nomodule.min.js)) and serve them locally. +Alternative, you can download the files ([`mini-van-0.5.7.min.js`](https://vanjs.org/autodownload?file=mini-van-0.5.7.min.js), [`mini-van-0.5.7.nomodule.min.js`](https://vanjs.org/autodownload?file=mini-van-0.5.7.nomodule.min.js)) and serve them locally. You can find all relevant **Mini-Van** files in this [Download Table](https://vanjs.org/minivan#download-table). diff --git a/package-lock.json b/package-lock.json index dc1b5f0..d124b92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "mini-van-plate", - "version": "0.5.6", + "version": "0.5.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "mini-van-plate", - "version": "0.5.6", + "version": "0.5.7", "license": "MIT", "devDependencies": { "esbuild": "^0.17.19", diff --git a/package.json b/package.json index 16be691..43d4457 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mini-van-plate", - "version": "0.5.6", + "version": "0.5.7", "description": "A minimalist template engine for DOM generation and manipulation, working for both client-side and server-side rendering", "files": [ "src/mini-van.js", diff --git a/public/mini-van-0.5.7.d.ts b/public/mini-van-0.5.7.d.ts new file mode 100644 index 0000000..2796707 --- /dev/null +++ b/public/mini-van-0.5.7.d.ts @@ -0,0 +1,75 @@ +export interface State { + val: T + readonly oldVal: T + readonly rawVal: T +} + +// Defining readonly view of State for covariance. +// Basically we want StateView to implement StateView +export type StateView = Readonly> + +export type Primitive = string | number | boolean | bigint + +export type PropValue = Primitive | ((e: any) => void) | null + +export type Props = Record | (() => PropValue)> + +interface HasFirstChild {firstChild?: unknown} + +type NodeType = + Omit + +export type ValidChildDomValue = + Primitive | ElementType | NodeType | TextNodeType | null | undefined + +export type BindingFunc = + | ((dom?: ElementType | TextNodeType) => ValidChildDomValue) + | ((dom?: ElementType) => ElementType) + +export type ChildDom = + | ValidChildDomValue + | StateView + | BindingFunc + | readonly ChildDom[] + +type AddFunc = + (dom: ElementType, ...children: readonly ChildDom[]) => ElementType + +export type TagFunc = + (first?: Props | ChildDom, + ...rest: readonly ChildDom[]) => ResultType + +type Tags = + Readonly>> + +// Tags type in browser context, which contains the signatures to tag functions that return +// specialized DOM elements. +type BrowserTags = Tags & { + [K in keyof HTMLElementTagNameMap]: TagFunc +} + +declare function state(): State +declare function state(initVal: T): State + +export interface VanObj { + readonly state: typeof state + readonly derive: (f: () => T) => State + readonly add: AddFunc + readonly tags: Tags & ((namespaceURI: string) => Tags) + + // Mini-Van specific API + html: (first?: Props | ChildDom, + ...rest: readonly ChildDom[]) => string +} + +export interface Van extends VanObj { + readonly vanWithDoc: (doc: { + createElement(s: any): ElementType, + createTextNode(s: any): TextNodeType, + }) => VanObj + readonly tags: BrowserTags & ((namespaceURI: string) => Tags) +} + +declare const van: Van + +export default van diff --git a/public/mini-van-0.5.7.js b/public/mini-van-0.5.7.js new file mode 100644 index 0000000..ae2613c --- /dev/null +++ b/public/mini-van-0.5.7.js @@ -0,0 +1,48 @@ +/// + +// This file consistently uses `let` keyword instead of `const` for reducing the bundle size. + +// Aliasing some builtin symbols to reduce the bundle size. +let protoOf = Object.getPrototypeOf, _undefined, funcProto = protoOf(protoOf) + +let stateProto = {get oldVal() { return this.val }, get rawVal() { return this.val }} +let objProto = protoOf(stateProto) + +let state = initVal => ({__proto__: stateProto, val: initVal}) + +let plainValue = (k, v) => { + let protoOfV = protoOf(v ?? 0) + return protoOfV === stateProto ? v.val : + protoOfV !== funcProto || k?.startsWith("on") ? v : v() +} + +let add = (dom, ...children) => + (dom.append(...children.flat(Infinity) + .map(plainValue.bind(_undefined, _undefined)) + .filter(c => c != _undefined)), + dom) + +let vanWithDoc = doc => { + let tag = (ns, name, ...args) => { + let [props, ...children] = protoOf(args[0] ?? 0) === objProto ? args : [{}, ...args] + let dom = ns ? doc.createElementNS(ns, name) : doc.createElement(name) + for (let [k, v] of Object.entries(props)) { + let plainV = plainValue(k, v) + // Disable setting attribute for function-valued properties (mostly event handlers), + // as they're usually not useful for SSR (server-side rendering). + protoOf(plainV) !== funcProto && dom.setAttribute(k, plainV) + } + return add(dom, ...children) + } + + let handler = ns => ({get: (_, name) => tag.bind(_undefined, ns, name)}) + let tags = new Proxy(ns => new Proxy(tag, handler(ns)), handler()) + + return { + add, tags, state, derive: f => state(f()), + html: (...args) => "" + tags.html(...args).outerHTML, + } +} + +export default {"vanWithDoc": vanWithDoc, + ...vanWithDoc(typeof window !== "undefined" ? window.document : null)} diff --git a/public/mini-van-0.5.7.min.d.ts b/public/mini-van-0.5.7.min.d.ts new file mode 100644 index 0000000..2796707 --- /dev/null +++ b/public/mini-van-0.5.7.min.d.ts @@ -0,0 +1,75 @@ +export interface State { + val: T + readonly oldVal: T + readonly rawVal: T +} + +// Defining readonly view of State for covariance. +// Basically we want StateView to implement StateView +export type StateView = Readonly> + +export type Primitive = string | number | boolean | bigint + +export type PropValue = Primitive | ((e: any) => void) | null + +export type Props = Record | (() => PropValue)> + +interface HasFirstChild {firstChild?: unknown} + +type NodeType = + Omit + +export type ValidChildDomValue = + Primitive | ElementType | NodeType | TextNodeType | null | undefined + +export type BindingFunc = + | ((dom?: ElementType | TextNodeType) => ValidChildDomValue) + | ((dom?: ElementType) => ElementType) + +export type ChildDom = + | ValidChildDomValue + | StateView + | BindingFunc + | readonly ChildDom[] + +type AddFunc = + (dom: ElementType, ...children: readonly ChildDom[]) => ElementType + +export type TagFunc = + (first?: Props | ChildDom, + ...rest: readonly ChildDom[]) => ResultType + +type Tags = + Readonly>> + +// Tags type in browser context, which contains the signatures to tag functions that return +// specialized DOM elements. +type BrowserTags = Tags & { + [K in keyof HTMLElementTagNameMap]: TagFunc +} + +declare function state(): State +declare function state(initVal: T): State + +export interface VanObj { + readonly state: typeof state + readonly derive: (f: () => T) => State + readonly add: AddFunc + readonly tags: Tags & ((namespaceURI: string) => Tags) + + // Mini-Van specific API + html: (first?: Props | ChildDom, + ...rest: readonly ChildDom[]) => string +} + +export interface Van extends VanObj { + readonly vanWithDoc: (doc: { + createElement(s: any): ElementType, + createTextNode(s: any): TextNodeType, + }) => VanObj + readonly tags: BrowserTags & ((namespaceURI: string) => Tags) +} + +declare const van: Van + +export default van diff --git a/public/mini-van-0.5.7.min.js b/public/mini-van-0.5.7.min.js new file mode 100644 index 0000000..ed82d89 --- /dev/null +++ b/public/mini-van-0.5.7.min.js @@ -0,0 +1 @@ +let t,e=Object.getPrototypeOf,r=e(e),l={get oldVal(){return this.val},get rawVal(){return this.val}},n=e(l),o=t=>({__proto__:l,val:t}),a=(t,n)=>{let o=e(n??0);return o===l?n.val:o!==r||t?.startsWith("on")?n:n()},d=(e,...r)=>(e.append(...r.flat(1/0).map(a.bind(t,t)).filter(e=>e!=t)),e),u=l=>{let u=(t,o,...u)=>{let[i,...w]=e(u[0]??0)===n?u:[{},...u],f=t?l.createElementNS(t,o):l.createElement(o);for(let[t,l]of Object.entries(i)){let n=a(t,l);e(n)!==r&&f.setAttribute(t,n)}return d(f,...w)},i=e=>({get:(r,l)=>u.bind(t,e,l)}),w=new Proxy(t=>new Proxy(u,i(t)),i());return{add:d,tags:w,state:o,derive:t=>o(t()),html:(...t)=>""+w.html(...t).outerHTML}};export default{vanWithDoc:u,...u("undefined"!=typeof window?window.document:null)}; \ No newline at end of file diff --git a/public/mini-van-0.5.7.nomodule.js b/public/mini-van-0.5.7.nomodule.js new file mode 100644 index 0000000..dfaa60a --- /dev/null +++ b/public/mini-van-0.5.7.nomodule.js @@ -0,0 +1,45 @@ +(() => { + // mini-van.js + var protoOf = Object.getPrototypeOf; + var _undefined; + var funcProto = protoOf(protoOf); + var stateProto = { get oldVal() { + return this.val; + }, get rawVal() { + return this.val; + } }; + var objProto = protoOf(stateProto); + var state = (initVal) => ({ __proto__: stateProto, val: initVal }); + var plainValue = (k, v) => { + let protoOfV = protoOf(v ?? 0); + return protoOfV === stateProto ? v.val : protoOfV !== funcProto || k?.startsWith("on") ? v : v(); + }; + var add = (dom, ...children) => (dom.append(...children.flat(Infinity).map(plainValue.bind(_undefined, _undefined)).filter((c) => c != _undefined)), dom); + var vanWithDoc = (doc) => { + let tag = (ns, name, ...args) => { + let [props, ...children] = protoOf(args[0] ?? 0) === objProto ? args : [{}, ...args]; + let dom = ns ? doc.createElementNS(ns, name) : doc.createElement(name); + for (let [k, v] of Object.entries(props)) { + let plainV = plainValue(k, v); + protoOf(plainV) !== funcProto && dom.setAttribute(k, plainV); + } + return add(dom, ...children); + }; + let handler = (ns) => ({ get: (_, name) => tag.bind(_undefined, ns, name) }); + let tags = new Proxy((ns) => new Proxy(tag, handler(ns)), handler()); + return { + add, + tags, + state, + derive: (f) => state(f()), + html: (...args) => "" + tags.html(...args).outerHTML + }; + }; + var mini_van_default = { + "vanWithDoc": vanWithDoc, + ...vanWithDoc(typeof window !== "undefined" ? window.document : null) + }; + + // mini-van.forbundle.js + window.van = mini_van_default; +})(); diff --git a/public/mini-van-0.5.7.nomodule.min.js b/public/mini-van-0.5.7.nomodule.min.js new file mode 100644 index 0000000..c1beea4 --- /dev/null +++ b/public/mini-van-0.5.7.nomodule.min.js @@ -0,0 +1 @@ +{let t,e,r,n,l,o,a,d,w,i;e=Object.getPrototypeOf,r=e(e),l=e(n={get oldVal(){return this.val},get rawVal(){return this.val}}),o=t=>({__proto__:n,val:t}),a=(t,l)=>{let o=e(l??0);return o===n?l.val:o!==r||t?.startsWith("on")?l:l()},d=(e,...r)=>(e.append(...r.flat(1/0).map(a.bind(t,t)).filter(e=>e!=t)),e),i={vanWithDoc:w=n=>{let w=(t,o,...w)=>{let[i,...u]=e(w[0]??0)===l?w:[{},...w],h=t?n.createElementNS(t,o):n.createElement(o);for(let[t,n]of Object.entries(i)){let l=a(t,n);e(l)!==r&&h.setAttribute(t,l)}return d(h,...u)},i=e=>({get:(r,n)=>w.bind(t,e,n)}),u=new Proxy(t=>new Proxy(w,i(t)),i());return{add:d,tags:u,state:o,derive:t=>o(t()),html:(...t)=>""+u.html(...t).outerHTML}},...w("undefined"!=typeof window?window.document:null)},window.van=i;} \ No newline at end of file diff --git a/public/mini-van-latest.d.ts b/public/mini-van-latest.d.ts index 4491aa7..2796707 100644 --- a/public/mini-van-latest.d.ts +++ b/public/mini-van-latest.d.ts @@ -1,6 +1,7 @@ export interface State { val: T readonly oldVal: T + readonly rawVal: T } // Defining readonly view of State for covariance. diff --git a/public/mini-van-latest.js b/public/mini-van-latest.js index 39a2788..ae2613c 100644 --- a/public/mini-van-latest.js +++ b/public/mini-van-latest.js @@ -5,7 +5,8 @@ // Aliasing some builtin symbols to reduce the bundle size. let protoOf = Object.getPrototypeOf, _undefined, funcProto = protoOf(protoOf) -let stateProto = {get oldVal() { return this.val }}, objProto = protoOf(stateProto) +let stateProto = {get oldVal() { return this.val }, get rawVal() { return this.val }} +let objProto = protoOf(stateProto) let state = initVal => ({__proto__: stateProto, val: initVal}) diff --git a/public/mini-van-latest.min.d.ts b/public/mini-van-latest.min.d.ts index 4491aa7..2796707 100644 --- a/public/mini-van-latest.min.d.ts +++ b/public/mini-van-latest.min.d.ts @@ -1,6 +1,7 @@ export interface State { val: T readonly oldVal: T + readonly rawVal: T } // Defining readonly view of State for covariance. diff --git a/public/mini-van-latest.min.js b/public/mini-van-latest.min.js index 37bf7d1..ed82d89 100644 --- a/public/mini-van-latest.min.js +++ b/public/mini-van-latest.min.js @@ -1 +1 @@ -let t,e=Object.getPrototypeOf,l=e(e),r={get oldVal(){return this.val}},n=e(r),o=t=>({__proto__:r,val:t}),d=(t,n)=>{let o=e(n??0);return o===r?n.val:o!==l||t?.startsWith("on")?n:n()},a=(e,...l)=>(e.append(...l.flat(1/0).map(d.bind(t,t)).filter(e=>e!=t)),e),u=r=>{let u=(t,o,...u)=>{let[i,...w]=e(u[0]??0)===n?u:[{},...u],f=t?r.createElementNS(t,o):r.createElement(o);for(let[t,r]of Object.entries(i)){let n=d(t,r);e(n)!==l&&f.setAttribute(t,n)}return a(f,...w)},i=e=>({get:(l,r)=>u.bind(t,e,r)}),w=new Proxy(t=>new Proxy(u,i(t)),i());return{add:a,tags:w,state:o,derive:t=>o(t()),html:(...t)=>""+w.html(...t).outerHTML}};export default{vanWithDoc:u,...u("undefined"!=typeof window?window.document:null)}; \ No newline at end of file +let t,e=Object.getPrototypeOf,r=e(e),l={get oldVal(){return this.val},get rawVal(){return this.val}},n=e(l),o=t=>({__proto__:l,val:t}),a=(t,n)=>{let o=e(n??0);return o===l?n.val:o!==r||t?.startsWith("on")?n:n()},d=(e,...r)=>(e.append(...r.flat(1/0).map(a.bind(t,t)).filter(e=>e!=t)),e),u=l=>{let u=(t,o,...u)=>{let[i,...w]=e(u[0]??0)===n?u:[{},...u],f=t?l.createElementNS(t,o):l.createElement(o);for(let[t,l]of Object.entries(i)){let n=a(t,l);e(n)!==r&&f.setAttribute(t,n)}return d(f,...w)},i=e=>({get:(r,l)=>u.bind(t,e,l)}),w=new Proxy(t=>new Proxy(u,i(t)),i());return{add:d,tags:w,state:o,derive:t=>o(t()),html:(...t)=>""+w.html(...t).outerHTML}};export default{vanWithDoc:u,...u("undefined"!=typeof window?window.document:null)}; \ No newline at end of file diff --git a/public/mini-van-latest.nomodule.js b/public/mini-van-latest.nomodule.js index df0d0d1..dfaa60a 100644 --- a/public/mini-van-latest.nomodule.js +++ b/public/mini-van-latest.nomodule.js @@ -5,6 +5,8 @@ var funcProto = protoOf(protoOf); var stateProto = { get oldVal() { return this.val; + }, get rawVal() { + return this.val; } }; var objProto = protoOf(stateProto); var state = (initVal) => ({ __proto__: stateProto, val: initVal }); diff --git a/public/mini-van-latest.nomodule.min.js b/public/mini-van-latest.nomodule.min.js index d04fbce..c1beea4 100644 --- a/public/mini-van-latest.nomodule.min.js +++ b/public/mini-van-latest.nomodule.min.js @@ -1 +1 @@ -{let t,e,n,r,o,l,d,w,a,i;e=Object.getPrototypeOf,n=e(e),o=e(r={get oldVal(){return this.val}}),l=t=>({__proto__:r,val:t}),d=(t,o)=>{let l=e(o??0);return l===r?o.val:l!==n||t?.startsWith("on")?o:o()},w=(e,...n)=>(e.append(...n.flat(1/0).map(d.bind(t,t)).filter(e=>e!=t)),e),i={vanWithDoc:a=r=>{let a=(t,l,...a)=>{let[i,...u]=e(a[0]??0)===o?a:[{},...a],f=t?r.createElementNS(t,l):r.createElement(l);for(let[t,r]of Object.entries(i)){let o=d(t,r);e(o)!==n&&f.setAttribute(t,o)}return w(f,...u)},i=e=>({get:(n,r)=>a.bind(t,e,r)}),u=new Proxy(t=>new Proxy(a,i(t)),i());return{add:w,tags:u,state:l,derive:t=>l(t()),html:(...t)=>""+u.html(...t).outerHTML}},...a("undefined"!=typeof window?window.document:null)},window.van=i;} \ No newline at end of file +{let t,e,r,n,l,o,a,d,w,i;e=Object.getPrototypeOf,r=e(e),l=e(n={get oldVal(){return this.val},get rawVal(){return this.val}}),o=t=>({__proto__:n,val:t}),a=(t,l)=>{let o=e(l??0);return o===n?l.val:o!==r||t?.startsWith("on")?l:l()},d=(e,...r)=>(e.append(...r.flat(1/0).map(a.bind(t,t)).filter(e=>e!=t)),e),i={vanWithDoc:w=n=>{let w=(t,o,...w)=>{let[i,...u]=e(w[0]??0)===l?w:[{},...w],h=t?n.createElementNS(t,o):n.createElement(o);for(let[t,n]of Object.entries(i)){let l=a(t,n);e(l)!==r&&h.setAttribute(t,l)}return d(h,...u)},i=e=>({get:(r,n)=>w.bind(t,e,n)}),u=new Proxy(t=>new Proxy(w,i(t)),i());return{add:d,tags:u,state:o,derive:t=>o(t()),html:(...t)=>""+u.html(...t).outerHTML}},...w("undefined"!=typeof window?window.document:null)},window.van=i;} \ No newline at end of file diff --git a/public/mini-van.version b/public/mini-van.version index ad83b1b..dc2b74e 100644 --- a/public/mini-van.version +++ b/public/mini-van.version @@ -1 +1 @@ -0.5.6 \ No newline at end of file +0.5.7 \ No newline at end of file diff --git a/src/mini-van.d.ts b/src/mini-van.d.ts index 4491aa7..2796707 100644 --- a/src/mini-van.d.ts +++ b/src/mini-van.d.ts @@ -1,6 +1,7 @@ export interface State { val: T readonly oldVal: T + readonly rawVal: T } // Defining readonly view of State for covariance. diff --git a/src/mini-van.js b/src/mini-van.js index 39a2788..ae2613c 100644 --- a/src/mini-van.js +++ b/src/mini-van.js @@ -5,7 +5,8 @@ // Aliasing some builtin symbols to reduce the bundle size. let protoOf = Object.getPrototypeOf, _undefined, funcProto = protoOf(protoOf) -let stateProto = {get oldVal() { return this.val }}, objProto = protoOf(stateProto) +let stateProto = {get oldVal() { return this.val }, get rawVal() { return this.val }} +let objProto = protoOf(stateProto) let state = initVal => ({__proto__: stateProto, val: initVal}) diff --git a/src/shared.d.ts b/src/shared.d.ts index 95e35c5..8100ebd 100644 --- a/src/shared.d.ts +++ b/src/shared.d.ts @@ -1,6 +1,7 @@ export interface State { val: T; readonly oldVal: T; + readonly rawVal: T; } export type StateView = Readonly>; export type Primitive = string | number | boolean | bigint; diff --git a/src/shared.ts b/src/shared.ts index a076df4..2fade6e 100644 --- a/src/shared.ts +++ b/src/shared.ts @@ -1,6 +1,7 @@ export interface State { val: T readonly oldVal: T + readonly rawVal: T } // Defining readonly view of State for covariance. diff --git a/src/van-plate.d.ts b/src/van-plate.d.ts index 83fec40..c6c3f31 100644 --- a/src/van-plate.d.ts +++ b/src/van-plate.d.ts @@ -1,6 +1,7 @@ export interface State { val: T readonly oldVal: T + readonly rawVal: T } // Defining readonly view of State for covariance. diff --git a/src/van-plate.js b/src/van-plate.js index 5f6c2d0..e0edfa1 100644 --- a/src/van-plate.js +++ b/src/van-plate.js @@ -31,7 +31,7 @@ const escapeAttr = v => v.replace(/"/g, """) const protoOf = Object.getPrototypeOf, funcProto = protoOf(protoOf), objProto = protoOf(noChild) -const stateProto = {get oldVal() { return this.val }} +const stateProto = {get oldVal() { return this.val }, get rawVal() { return this.val }} const state = initVal => ({__proto__: stateProto, val: initVal}) diff --git a/test/deno/van-plate.test.ts b/test/deno/van-plate.test.ts index 73f4eb2..c5c5df0 100644 --- a/test/deno/van-plate.test.ts +++ b/test/deno/van-plate.test.ts @@ -146,7 +146,7 @@ Deno.test("dummy reactive", () => { "data-index": state1, "data-id": () => state2.val + 2, "data-title": state3, - "data-text": () => `Prefix - ${state4.oldVal} - Suffix`, + "data-text": () => `Prefix - ${state4.rawVal} - Suffix`, }, () => state1.val, () => state2.oldVal, state3, () => state4.val), button({onclick: van.derive(() => state5.val ? 'console.log("Hello")' : 'alert("Hello")')}, "Button1" @@ -156,7 +156,7 @@ Deno.test("dummy reactive", () => { "Button2" ), () => (state5.val ? pre : div)(state3), - () => (state6.oldVal ? pre : div)(state4), + () => (state6.rawVal ? pre : div)(state4), ) assertEquals(dom.render(), '
12

Prefix - abc

abcabc - Suffix

12abcabcabc

abc
abcabc
') }) diff --git a/test/mini-van.test.js b/test/mini-van.test.js index 2ee0ce5..d7bc45f 100644 --- a/test/mini-van.test.js +++ b/test/mini-van.test.js @@ -94,8 +94,8 @@ const runTests = (van, msgDom) => { "data-index": state1, "data-id": () => state2.val + 2, "data-title": state3, - "data-text": () => `Prefix - ${state4.oldVal} - Suffix`, - }, () => state1.val, () => state2.oldVal, state3, () => state4.val), button({ onclick: van.derive(() => state5.val ? 'console.log("Hello")' : 'alert("Hello")') }, "Button1"), button({ onclick: van.derive(() => state6.val ? () => console.log("Hello") : () => alert("Hello")) }, "Button2"), () => (state5.val ? pre : div)(state3), () => (state6.oldVal ? pre : div)(state4)); + "data-text": () => `Prefix - ${state4.rawVal} - Suffix`, + }, () => state1.val, () => state2.oldVal, state3, () => state4.val), button({ onclick: van.derive(() => state5.val ? 'console.log("Hello")' : 'alert("Hello")') }, "Button1"), button({ onclick: van.derive(() => state6.val ? () => console.log("Hello") : () => alert("Hello")) }, "Button2"), () => (state5.val ? pre : div)(state3), () => (state6.rawVal ? pre : div)(state4)); assertEq(dom.outerHTML, '
12

Prefix - abc

abcabc - Suffix

12abcabcabc

abc
abcabc
'); }, fragment: () => { diff --git a/test/mini-van.test.nomodule.js b/test/mini-van.test.nomodule.js index 7d66e51..61a6b94 100644 --- a/test/mini-van.test.nomodule.js +++ b/test/mini-van.test.nomodule.js @@ -89,8 +89,8 @@ "data-index": state1, "data-id": () => state2.val + 2, "data-title": state3, - "data-text": () => `Prefix - ${state4.oldVal} - Suffix` - }, () => state1.val, () => state2.oldVal, state3, () => state4.val), button({ onclick: van2.derive(() => state5.val ? 'console.log("Hello")' : 'alert("Hello")') }, "Button1"), button({ onclick: van2.derive(() => state6.val ? () => console.log("Hello") : () => alert("Hello")) }, "Button2"), () => (state5.val ? pre : div2)(state3), () => (state6.oldVal ? pre : div2)(state4)); + "data-text": () => `Prefix - ${state4.rawVal} - Suffix` + }, () => state1.val, () => state2.oldVal, state3, () => state4.val), button({ onclick: van2.derive(() => state5.val ? 'console.log("Hello")' : 'alert("Hello")') }, "Button1"), button({ onclick: van2.derive(() => state6.val ? () => console.log("Hello") : () => alert("Hello")) }, "Button2"), () => (state5.val ? pre : div2)(state3), () => (state6.rawVal ? pre : div2)(state4)); assertEq(dom.outerHTML, '
12

Prefix - abc

abcabc - Suffix

12abcabcabc

abc
abcabc
'); }, fragment: () => { diff --git a/test/mini-van.test.ts b/test/mini-van.test.ts index 052f68a..467813b 100644 --- a/test/mini-van.test.ts +++ b/test/mini-van.test.ts @@ -133,7 +133,7 @@ const runTests = (van: Van, msgDom: Element) => { "data-index": state1, "data-id": () => state2.val + 2, "data-title": state3, - "data-text": () => `Prefix - ${state4.oldVal} - Suffix`, + "data-text": () => `Prefix - ${state4.rawVal} - Suffix`, }, () => state1.val, () => state2.oldVal, state3, () => state4.val), button({onclick: van.derive(() => state5.val ? 'console.log("Hello")' : 'alert("Hello")')}, "Button1" @@ -143,7 +143,7 @@ const runTests = (van: Van, msgDom: Element) => { "Button2" ), () => (state5.val ? pre : div)(state3), - () => (state6.oldVal ? pre : div)(state4), + () => (state6.rawVal ? pre : div)(state4), ) assertEq(dom.outerHTML, '
12

Prefix - abc

abcabc - Suffix

12abcabcabc

abc
abcabc
') },