diff --git a/dom-expressions.config.js b/dom-expressions.config.js index c8e157c..0a5e8dc 100644 --- a/dom-expressions.config.js +++ b/dom-expressions.config.js @@ -2,7 +2,15 @@ module.exports = { output: 'src/runtime.js', includeTypes: true, variables: { - imports: [ `import wrap from 's-js'` ], - includeContext: false + imports: [ `import wrap, {value, sample as ignore} from 's-js'` ], + declarations: { + wrapCondition: `(fn) => { + const s = value(ignore(fn)); + wrap(() => s(fn())) + return s; + }` + }, + includeContext: false, + wrapConditionals: true } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 9a54936..0052584 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,33 +1,34 @@ { "name": "s-jsx", - "version": "0.1.0", + "version": "0.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.0.tgz", + "integrity": "sha512-AN2IR/wCUYsM+PdErq6Bp3RFTXl8W0p9Nmymm7zkpsCmh+r/YYcckaCGpU8Q/mEKmST19kkGRaG42A/jxOWwBA==", "dev": true, "requires": { - "@babel/highlight": "^7.0.0" + "@babel/highlight": "^7.8.0" } }, "@babel/core": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.4.tgz", - "integrity": "sha512-Rm0HGw101GY8FTzpWSyRbki/jzq+/PkNQJ+nSulrdY6gFGOsNseCqD6KHRYe2E+EdzuBdr2pxCp6s4Uk6eJ+XQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.4", - "@babel/helpers": "^7.6.2", - "@babel/parser": "^7.6.4", - "@babel/template": "^7.6.0", - "@babel/traverse": "^7.6.3", - "@babel/types": "^7.6.3", - "convert-source-map": "^1.1.0", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.0.tgz", + "integrity": "sha512-3rqPi/bv/Xfu2YzHvBz4XqMI1fKVwnhntPA1/fjoECrSjrhbOCxlTrbVu5gUtr8zkxW+RpkDOa/HCW93gzS2Dw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.0", + "@babel/generator": "^7.8.0", + "@babel/helpers": "^7.8.0", + "@babel/parser": "^7.8.0", + "@babel/template": "^7.8.0", + "@babel/traverse": "^7.8.0", + "@babel/types": "^7.8.0", + "convert-source-map": "^1.7.0", "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", "json5": "^2.1.0", "lodash": "^4.17.13", "resolve": "^1.3.2", @@ -36,120 +37,120 @@ } }, "@babel/generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.4.tgz", - "integrity": "sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.0.tgz", + "integrity": "sha512-2Lp2e02CV2C7j/H4n4D9YvsvdhPVVg9GDIamr6Tu4tU35mL3mzOrzl1lZ8ZJtysfZXh+y+AGORc2rPS7yHxBUg==", "dev": true, "requires": { - "@babel/types": "^7.6.3", + "@babel/types": "^7.8.0", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" } }, "@babel/helper-create-class-features-plugin": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.6.0.tgz", - "integrity": "sha512-O1QWBko4fzGju6VoVvrZg0RROCVifcLxiApnGP3OWfWzvxRZFCoBD81K5ur5e3bVY2Vf/5rIJm8cqPKn8HUJng==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.0.tgz", + "integrity": "sha512-ctCvqYBTlwEl2uF4hCxE0cd/sSw71Zfag0jKa39y4HDLh0BQ4PVBX1384Ye8GqrEZ69xgLp9fwPbv3GgIDDF2Q==", "dev": true, "requires": { - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-member-expression-to-functions": "^7.5.5", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/helper-replace-supers": "^7.5.5", - "@babel/helper-split-export-declaration": "^7.4.4" + "@babel/helper-function-name": "^7.8.0", + "@babel/helper-member-expression-to-functions": "^7.8.0", + "@babel/helper-optimise-call-expression": "^7.8.0", + "@babel/helper-plugin-utils": "^7.8.0", + "@babel/helper-replace-supers": "^7.8.0", + "@babel/helper-split-export-declaration": "^7.8.0" } }, "@babel/helper-function-name": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", - "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.0.tgz", + "integrity": "sha512-x9psucuU0Xalw+0Vpr2FYJMLB7/KnPSLZhlkUyOGbYAWRDfmtZBrguYpJYiaNCRV7vGkYjO/gF6/J6yMvdWTDw==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" + "@babel/helper-get-function-arity": "^7.8.0", + "@babel/template": "^7.8.0", + "@babel/types": "^7.8.0" } }, "@babel/helper-get-function-arity": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", - "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.0.tgz", + "integrity": "sha512-eUP5grliToMapQiTaYS2AAO/WwaCG7cuJztR1v/a1aPzUzUeGt+AaI9OvLATc/AfFkF8SLJ10d5ugGt/AQ9d6w==", "dev": true, "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.8.0" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz", - "integrity": "sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.0.tgz", + "integrity": "sha512-0m1QabGrdXuoxX/g+KOAGndoHwskC70WweqHRQyCsaO67KOEELYh4ECcGw6ZGKjDKa5Y7SW4Qbhw6ly4Fah/jQ==", "dev": true, "requires": { - "@babel/types": "^7.5.5" + "@babel/types": "^7.8.0" } }, "@babel/helper-module-imports": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", - "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.0.tgz", + "integrity": "sha512-ylY9J6ZxEcjmJaJ4P6aVs/fZdrZVctCGnxxfYXwCnSMapqd544zT8lWK2qI/vBPjE5gS0o2jILnH+AkpsPauEQ==", "dev": true, "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.8.0" } }, "@babel/helper-optimise-call-expression": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", - "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.0.tgz", + "integrity": "sha512-aiJt1m+K57y0n10fTw+QXcCXzmpkG+o+NoQmAZqlZPstkTE0PZT+Z27QSd/6Gf00nuXJQO4NiJ0/YagSW5kC2A==", "dev": true, "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.8.0" } }, "@babel/helper-plugin-utils": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", - "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.0.tgz", + "integrity": "sha512-+hAlRGdf8fHQAyNnDBqTHQhwdLURLdrCROoWaEQYiQhk2sV9Rhs+GoFZZfMJExTq9HG8o2NX3uN2G90bFtmFdA==", "dev": true }, "@babel/helper-replace-supers": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz", - "integrity": "sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.0.tgz", + "integrity": "sha512-R2CyorW4tcO3YzdkClLpt6MS84G+tPkOi0MmiCn1bvYVnmDpdl9R15XOi3NQW2mhOAEeBnuQ4g1Bh7pT2sX8fg==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.5.5", - "@babel/helper-optimise-call-expression": "^7.0.0", - "@babel/traverse": "^7.5.5", - "@babel/types": "^7.5.5" + "@babel/helper-member-expression-to-functions": "^7.8.0", + "@babel/helper-optimise-call-expression": "^7.8.0", + "@babel/traverse": "^7.8.0", + "@babel/types": "^7.8.0" } }, "@babel/helper-split-export-declaration": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", - "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.0.tgz", + "integrity": "sha512-YhYFhH4T6DlbT6CPtVgLfC1Jp2gbCawU/ml7WJvUpBg01bCrXSzTYMZZXbbIGjq/kHmK8YUATxTppcRGzj31pA==", "dev": true, "requires": { - "@babel/types": "^7.4.4" + "@babel/types": "^7.8.0" } }, "@babel/helpers": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.6.2.tgz", - "integrity": "sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.0.tgz", + "integrity": "sha512-srWKpjAFbiut5JoCReZJ098hLqoZ9HufOnKZPggc7j74XaPuQ+9b3RYPV1M/HfjL63lCNd8uI1O487qIWxAFNA==", "dev": true, "requires": { - "@babel/template": "^7.6.0", - "@babel/traverse": "^7.6.2", - "@babel/types": "^7.6.0" + "@babel/template": "^7.8.0", + "@babel/traverse": "^7.8.0", + "@babel/types": "^7.8.0" } }, "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.0.tgz", + "integrity": "sha512-OsdTJbHlPtIk2mmtwXItYrdmalJ8T0zpVzNAbKSkHshuywj7zb29Y09McV/jQsQunc/nEyHiPV2oy9llYMLqxw==", "dev": true, "requires": { "chalk": "^2.0.0", @@ -158,73 +159,73 @@ } }, "@babel/parser": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.4.tgz", - "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.0.tgz", + "integrity": "sha512-VVtsnUYbd1+2A2vOVhm4P2qNXQE8L/W859GpUHfUcdhX8d3pEKThZuIr6fztocWx9HbK+00/CR0tXnhAggJ4CA==", "dev": true }, "@babel/plugin-syntax-typescript": { - "version": "7.3.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.3.3.tgz", - "integrity": "sha512-dGwbSMA1YhVS8+31CnPR7LB4pcbrzcV99wQzby4uAfrkZPYZlQ7ImwdpzLqi6Z6IL02b8IAL379CaMwo0x5Lag==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.8.0.tgz", + "integrity": "sha512-LrvVrabb993Ve5fzXsyEkfYCuhpXBwsUFjlvgD8UmXXg3r/8/ceooSdRvjdmtPXXz+lHaqZHZooV1jMWer2qkA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.8.0" } }, "@babel/plugin-transform-typescript": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.6.3.tgz", - "integrity": "sha512-aiWINBrPMSC3xTXRNM/dfmyYuPNKY/aexYqBgh0HBI5Y+WO5oRAqW/oROYeYHrF4Zw12r9rK4fMk/ZlAmqx/FQ==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.8.0.tgz", + "integrity": "sha512-RhMZnNWcyvX+rM6mk888MaeoVl5pGfmYP3as709n4+0d15SRedz4r+LPRg2a9s4z+t+DM+gy8uz/rmM3Cb8JBw==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.6.0", - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-syntax-typescript": "^7.2.0" + "@babel/helper-create-class-features-plugin": "^7.8.0", + "@babel/helper-plugin-utils": "^7.8.0", + "@babel/plugin-syntax-typescript": "^7.8.0" } }, "@babel/preset-typescript": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.6.0.tgz", - "integrity": "sha512-4xKw3tTcCm0qApyT6PqM9qniseCE79xGHiUnNdKGdxNsGUc2X7WwZybqIpnTmoukg3nhPceI5KPNzNqLNeIJww==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.8.0.tgz", + "integrity": "sha512-mvu4OmrLK6qRPiXlOkE4yOeOszHzk9itwe6aiMN0RL9Bc5uAwAotVTy4kKl17evLMd1WsvWT1O3mZltynuqxXg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-transform-typescript": "^7.6.0" + "@babel/helper-plugin-utils": "^7.8.0", + "@babel/plugin-transform-typescript": "^7.8.0" } }, "@babel/template": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz", - "integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.0.tgz", + "integrity": "sha512-0NNMDsY2t3ltAVVK1WHNiaePo3tXPUeJpCX4I3xSKFoEl852wJHG8mrgHVADf8Lz1y+8al9cF7cSSfzSnFSYiw==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.0" + "@babel/code-frame": "^7.8.0", + "@babel/parser": "^7.8.0", + "@babel/types": "^7.8.0" } }, "@babel/traverse": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", - "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.0.tgz", + "integrity": "sha512-d/6sPXFLGlJHZO/zWDtgFaKyalCOHLedzxpVJn6el1cw+f2TZa7xZEszeXdOw6EUemqRFBAn106BWBvtSck9Qw==", "dev": true, "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.3", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.3", - "@babel/types": "^7.6.3", + "@babel/code-frame": "^7.8.0", + "@babel/generator": "^7.8.0", + "@babel/helper-function-name": "^7.8.0", + "@babel/helper-split-export-declaration": "^7.8.0", + "@babel/parser": "^7.8.0", + "@babel/types": "^7.8.0", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", - "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.0.tgz", + "integrity": "sha512-1RF84ehyx9HH09dMMwGWl3UTWlVoCPtqqJPjGuC4JzMe1ZIVDJ2DT8mv3cPv/A7veLD6sgR7vi95lJqm+ZayIg==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -233,15 +234,15 @@ } }, "@types/estree": { - "version": "0.0.39", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", - "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.42.tgz", + "integrity": "sha512-K1DPVvnBCPxzD+G51/cxVIoc2X8uUVl1zpJeE6iKcgHMj4+tbat5Xu4TjV7v2QSDbIeAfLi2hIk+u2+s0MlpUQ==", "dev": true }, "@types/node": { - "version": "12.11.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.11.1.tgz", - "integrity": "sha512-TJtwsqZ39pqcljJpajeoofYRfeZ7/I/OMUQ5pR4q5wOKf2ocrUvBAZUMhWsOvKx3dVc/aaV5GluBivt0sWqA5A==", + "version": "13.1.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.1.6.tgz", + "integrity": "sha512-Jg1F+bmxcpENHP23sVKkNuU3uaxPnsBMW0cLjleiikFKomJQbsn0Cqk2yDvQArqzZN6ABfBkZ0To7pQ8sLdWDg==", "dev": true }, "@types/resolve": { @@ -301,9 +302,9 @@ "dev": true }, "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "dev": true, "requires": { "safe-buffer": "~5.1.1" @@ -319,18 +320,18 @@ } }, "dom-expressions": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/dom-expressions/-/dom-expressions-0.13.0.tgz", - "integrity": "sha512-0cf0R+illaZFxqnYQoH+4DAoBDQaZ9QqIX0uJXQnBOxrkxFgNa0gEBKvUjQZ9eH5xuNFXu0FSJWI9/m6P5Xzmg==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/dom-expressions/-/dom-expressions-0.15.0.tgz", + "integrity": "sha512-cLdwLkjjsWsRB2Qh/OvKWFPKDnUiVP78QzD0DmY3+lvC0zGXhKNe2/cfCANzW3B5a2Xz9wK2r6ix29gXQOla7w==", "dev": true, "requires": { - "ejs": "^2.6.2" + "ejs": "^3.0.1" } }, "ejs": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.1.tgz", - "integrity": "sha512-kS/gEPzZs3Y1rRsbGX4UOSjtP/CeJP0CxSNZHYxGfVM/VgLcv0ZqM7C45YyTj2DI2g7+P9Dd24C+IMIg6D0nYQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.0.1.tgz", + "integrity": "sha512-cuIMtJwxvzumSAkqaaoGY/L6Fc/t6YvoP9/VIaK0V/CyqKLEQ8sqODmYfy/cjXEdZ9+OOL8TecbJu+1RsofGDw==", "dev": true }, "escape-string-regexp": { @@ -351,6 +352,12 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true + }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -364,9 +371,9 @@ "dev": true }, "hyper-dom-expressions": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/hyper-dom-expressions/-/hyper-dom-expressions-0.13.0.tgz", - "integrity": "sha512-dHYyBcaEh34MIGZ8TMAKfbw11Nz/LLUTquoJTqDLTajX66pG4dgV6UJ2JLZGDOzHWgympRahBaipgMP9C5Vj5g==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/hyper-dom-expressions/-/hyper-dom-expressions-0.15.0.tgz", + "integrity": "sha512-Ju5uNfMgx6yQLMaXcJl8qIcOaxbCFC9VZ7Y9E0D99/52QZPe+cPjthKmus9hocUp/2FYSzngE+xcw7hWgCgF/g==", "dev": true }, "is-module": { @@ -397,9 +404,9 @@ } }, "lit-dom-expressions": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/lit-dom-expressions/-/lit-dom-expressions-0.13.0.tgz", - "integrity": "sha512-AG+fzW4EBbAIn6UTqQ/o8N421Gj1Gk4o3hWGZuYSakkeOUlXWwAkDHrAzNxejCHo9Rn/XhTjV8fHAvmMYIU/cg==", + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/lit-dom-expressions/-/lit-dom-expressions-0.15.0.tgz", + "integrity": "sha512-vbu8bfr0VIkDcSUzx5I0OTsuXRDeeIpWpVGQzN2zZsbh+w+hmgyeQfLzABLICl5+1u1+mtigwPOOEMsG+EcOBQ==", "dev": true }, "lodash": { @@ -420,6 +427,12 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "ncp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", + "dev": true + }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", @@ -427,18 +440,18 @@ "dev": true }, "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.14.2.tgz", + "integrity": "sha512-EjlOBLBO1kxsUxsKjLt7TAECyKW6fOh1VRkykQkKGzcBbjjPIxBqGh0jf7GJ3k/f5mxMqW3htMD3WdTUVtW8HQ==", "dev": true, "requires": { "path-parse": "^1.0.6" } }, "rollup": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.24.0.tgz", - "integrity": "sha512-PiFETY/rPwodQ8TTC52Nz2DSCYUATznGh/ChnxActCr8rV5FIk3afBUb3uxNritQW/Jpbdn3kq1Rwh1HHYMwdQ==", + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.29.0.tgz", + "integrity": "sha512-V63Iz0dSdI5qPPN5HmCN6OBRzBFhMqNWcvwgq863JtSCTU6Vdvqq6S2fYle/dSCyoPrBkIP3EIr1RVs3HTRqqg==", "dev": true, "requires": { "@types/estree": "*", @@ -517,9 +530,9 @@ "dev": true }, "typescript": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz", - "integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==", + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.4.tgz", + "integrity": "sha512-A25xv5XCtarLwXpcDNZzCGvW2D1S3/bACratYBx2sax8PefsFhlYmkQicKHvpYflFS8if4zne5zT5kpJ7pzuvw==", "dev": true } } diff --git a/package.json b/package.json index 94b71f4..9f4fca2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "s-jsx", "description": "An alternative JSX renderer for S.js", - "version": "0.1.0", + "version": "0.2.0", "author": "Ryan Carniato", "license": "MIT", "repository": { @@ -16,15 +16,16 @@ "prepublishOnly": "npm run build" }, "devDependencies": { - "@babel/core": "7.6.4", - "@babel/preset-typescript": "7.6.0", - "dom-expressions": "0.13.0", - "hyper-dom-expressions": "~0.13.0", - "lit-dom-expressions": "~0.13.0", - "rollup": "^1.24.0", + "@babel/core": "7.8.0", + "@babel/preset-typescript": "7.8.0", + "dom-expressions": "0.15.0", + "hyper-dom-expressions": "~0.15.0", + "lit-dom-expressions": "~0.15.0", + "ncp": "2.0.0", + "rollup": "^1.29.0", "rollup-plugin-babel": "4.3.3", "rollup-plugin-node-resolve": "5.2.0", - "typescript": "3.6.4" + "typescript": "3.7.4" }, "dependencies": { "s-js": "~0.4.9" diff --git a/src/index.ts b/src/index.ts index 299ee9d..faa968c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ import S from 's-js'; export * from './runtime' -import { insert, hydration, startSSR } from "./runtime"; +import { insert, hydrate as hydr, renderToString as rTS } from "./runtime"; type MountableElement = Element | Document | ShadowRoot | DocumentFragment; @@ -14,15 +14,21 @@ export function render(code: () => any, mount: MountableElement): () => void { return dispose!; } -export function renderSSR(code: () => any, element: MountableElement): () => void { - startSSR(); - return render(code, element); +export function renderToString(code: () => any): Promise { + return S.root(dispose => { + const p = rTS(code); + dispose(); + return p; + }); } -export function hydrate(code: () => any, element: MountableElement): () => void { +export function hydrate( + code: () => any, + element: MountableElement +): () => void { let disposer: () => void; - hydration(() => { + hydr(() => { disposer = render(code, element); }, element); return disposer!; -} \ No newline at end of file +} diff --git a/src/runtime.d.ts b/src/runtime.d.ts index 82c0ba3..0931dcd 100644 --- a/src/runtime.d.ts +++ b/src/runtime.d.ts @@ -1,5 +1,6 @@ -export function template(html: string): HTMLTemplateElement; +export function template(html: string, isSVG?: boolean): Element; export function wrap(fn: (prev?: T) => T): any; +export function wrapCondition(fn: () => any): () => any; export function insert( parent: Element | Document | ShadowRoot | DocumentFragment, accessor: any, @@ -13,14 +14,30 @@ export function createComponent( ): any; export function delegateEvents(eventNames: string[]): void; export function clearDelegatedEvents(): void; -export function spread(node: Element, accessor: any, isSVG: Boolean): void; -export function classList(node: Element, value: { [k: string]: boolean }): void; +export function spread( + node: Element, + accessor: any, + isSVG?: Boolean, + skipChildren?: Boolean +): void; +export function classList( + node: Element, + value: { [k: string]: boolean }, + prev?: { [k: string]: boolean } +): void; export function currentContext(): any; -export function isSSR(): boolean; -export function startSSR(): void; -export function hydration( +export function renderToString( + fn: (done?: () => void) => any, + options?: { + timeoutMs?: number; + } +): Promise; +export function hydrate( fn: () => unknown, node: Element | Document | ShadowRoot | DocumentFragment ): void; -export function getNextElement(template: HTMLTemplateElement): Node; +export function getNextElement( + template: HTMLTemplateElement, + isSSR: boolean +): Node; export function getNextMarker(start: Node): [Node, Array]; diff --git a/src/runtime.js b/src/runtime.js index 8ed1232..27c39a6 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -1,17 +1,24 @@ import { Attributes, SVGAttributes, NonComposedEvents } from 'dom-expressions'; -import wrap from 's-js'; - +import wrap, {value, sample as ignore} from 's-js'; +const wrapCondition = (fn) => { + const s = value(ignore(fn)); + wrap(() => s(fn())) + return s; + }; const eventRegistry = new Set(); +const config = {}; -export { wrap }; +export { wrap, wrapCondition }; -export function template(html) { +export function template(html, isSVG) { const t = document.createElement('template'); t.innerHTML = html; if (t.innerHTML !== html) throw new Error(`Template html does not match input:\n${t.innerHTML}\n${html}`); - return t; + let node = t.content.firstChild; + if (isSVG) node = node.firstChild; + return node; } export function createComponent(Comp, props, dynamicKeys) { @@ -19,7 +26,7 @@ export function createComponent(Comp, props, dynamicKeys) { for (let i = 0; i < dynamicKeys.length; i++) dynamicProp(props, dynamicKeys[i]); } - return Comp(props); + return ignore(() => Comp(props)); } export function delegateEvents(eventNames) { @@ -37,20 +44,22 @@ export function clearDelegatedEvents() { eventRegistry.clear(); } -export function classList(node, value) { +export function classList(node, value, prev) { const classKeys = Object.keys(value); - for (let i = 0; i < classKeys.length; i++) { + for (let i = 0, len = classKeys.length; i < len; i++) { const key = classKeys[i], + classValue = value[key], classNames = key.split(/\s+/); - for (let j = 0; j < classNames.length; j++) - node.classList.toggle(classNames[j], value[key]); + if (prev && prev[key] === classValue) continue; + for (let j = 0, nameLen = classNames.length; j < nameLen; j++) + node.classList.toggle(classNames[j], classValue); } } -export function spread(node, accessor, isSVG) { +export function spread(node, accessor, isSVG, skipChildren) { if (typeof accessor === 'function') { - wrap(current => spreadExpression(node, accessor(), current, isSVG)); - } else spreadExpression(node, accessor, undefined, isSVG); + wrap(current => spreadExpression(node, accessor(), current, isSVG, skipChildren)); + } else spreadExpression(node, accessor, undefined, isSVG, skipChildren); } export function insert(parent, accessor, marker, initial) { @@ -65,44 +74,48 @@ export function insert(parent, accessor, marker, initial) { } // SSR -let hydrateRegistry = null, - hydrateKey = 0, - SSR = false; - -export function isSSR() { return SSR; } -export function startSSR() { - hydrateKey = 0; - SSR = true; -} - -export function hydration(code, root) { - hydrateRegistry = new Map(); - hydrateKey = 0; - SSR = false; - const iterator = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, { - acceptNode: node => node.hasAttribute('_hk') && NodeFilter.FILTER_ACCEPT +export function renderToString(code, options = {}) { + options = { timeoutMs: 10000, ...options } + config.hydrate = { id: '', count: 0 }; + const container = document.createElement("div"); + return new Promise(resolve => { + setTimeout(() => resolve(container.innerHTML), options.timeoutMs); + if (!code.length) { + insert(container, code()); + resolve(container.innerHTML); + } else insert(container, code(() => resolve(container.innerHTML))); }); - let node; - while (node = iterator.nextNode()) hydrateRegistry.set(node.getAttribute('_hk'), node); +} +export function hydrate(code, root) { + config.hydrate = { id: '', count: 0, registry: new Map() }; + const templates = root.querySelectorAll(`*[_hk]`); + for (let i = 0; i < templates.length; i++) { + const node = templates[i]; + config.hydrate.registry.set(node.getAttribute('_hk'), node); + } code(); - hydrateRegistry = null; + delete config.hydrate; } -export function getNextElement(template) { - if (!hydrateRegistry) { - const el = template.content.firstChild.cloneNode(true); - if (SSR) el.setAttribute('_hk', `${hydrateKey++}`); +export function getNextElement(template, isSSR) { + const hydrate = config.hydrate; + let node, key; + if (!hydrate || !hydrate.registry || !(node = hydrate.registry.get(key = `${hydrate.id}:${hydrate.count++}`))) { + const el = template.cloneNode(true); + if (isSSR && hydrate) + el.setAttribute('_hk', `${hydrate.id}:${hydrate.count++}`); return el; } - return hydrateRegistry.get(`${hydrateKey++}`); + if (window && window._$HYDRATION) window._$HYDRATION.completed.add(key); + return node; } export function getNextMarker(start) { let end = start, count = 0, current = []; - if (hydrateRegistry) { + if (config.hydrate && config.hydrate.registry) { while (end) { if (end.nodeType === 8) { const v = end.nodeValue; @@ -119,6 +132,18 @@ export function getNextMarker(start) { return [end, current]; } +export function runHydrationEvents(id) { + if (window && window._$HYDRATION) { + const { completed, events } = window._$HYDRATION; + while (events.length) { + const [id, e] = events[0]; + if (!completed.has(id)) return; + eventHandler(e); + events.shift(); + } + } +} + // Internal Functions function dynamicProp(props, key) { const src = props[key]; @@ -160,41 +185,57 @@ function eventHandler(e) { } } -function spreadExpression(node, props, prevProps = {}, isSVG) { +function spreadExpression(node, props, prevProps = {}, isSVG, skipChildren) { let info; - for (const prop in props) { - const value = props[prop]; - if (value === prevProps[prop]) continue; - if (prop === 'style') { - Object.assign(node.style, value); - } else if (prop === 'classList') { - classList(node, value); - // really only for forwarding from Components, can't forward normal ref - } else if (prop === 'ref' || prop === 'forwardRef') { - value(node); - } else if (prop.slice(0, 2) === 'on') { - const lc = prop.toLowerCase(); - if (lc !== prop && !NonComposedEvents.has(lc.slice(2))) { - const name = lc.slice(2); - node[`__${name}`] = value; - delegateEvents([name]); - } else node[lc] = value; - } else if (prop === 'events') { - for (const eventName in value) node.addEventListener(eventName, value[eventName]); - } else if (prop === 'children') { - insertExpression(node, value, prevProps[prop]); - } else if (info = Attributes[prop]) { - if (info.type === 'attribute') { - node.setAttribute(prop, value); - } else node[info.alias] = value; - } else if (isSVG) { - if (info = SVGAttributes[prop]) { - if (info.alias) node.setAttribute(info.alias, value); - else node.setAttribute(prop, value); - } else node.setAttribute(prop.replace(/([A-Z])/g, g => `-${g[0].toLowerCase()}`), value); - } else node[prop] = value; + if (!skipChildren && "children" in props) { + wrap(() => + (prevProps.children = insertExpression( + node, + props.children, + prevProps.children + )) + ); } - return Object.assign({}, props); + wrap(() => { + for (const prop in props) { + if (prop === "children") continue; + const value = props[prop]; + if (value === prevProps[prop]) continue; + if (prop === "style") { + Object.assign(node.style, value); + } else if (prop === "classList") { + classList(node, value, prevProps[prop]); + // really only for forwarding from Components, can't forward normal ref + } else if (prop === "ref" || prop === "forwardRef") { + value(node); + } else if (prop.slice(0, 2) === "on") { + const lc = prop.toLowerCase(); + if (lc !== prop && !NonComposedEvents.has(lc.slice(2))) { + const name = lc.slice(2); + node[`__${name}`] = value; + delegateEvents([name]); + } else node[lc] = value; + } else if (prop === "events") { + for (const eventName in value) + node.addEventListener(eventName, value[eventName]); + } else if ((info = Attributes[prop])) { + if (info.type === "attribute") { + node.setAttribute(prop, value); + } else node[info.alias] = value; + } else if (isSVG) { + if ((info = SVGAttributes[prop])) { + if (info.alias) node.setAttribute(info.alias, value); + else node.setAttribute(prop, value); + } else + node.setAttribute( + prop.replace(/([A-Z])/g, g => `-${g[0].toLowerCase()}`), + value + ); + } else node[prop] = value; + prevProps[prop] = value; + } + }); + return prevProps; } function normalizeIncomingArray(normalized, array) { @@ -239,6 +280,7 @@ function checkDynamicArray(array) { } function insertExpression(parent, value, current, marker) { + if (value === current) return current; const t = typeof value, multi = marker !== undefined; @@ -258,11 +300,14 @@ function insertExpression(parent, value, current, marker) { } else current = parent.textContent = value; } } else if (value == null || t === 'boolean') { + if (config.hydrate && config.hydrate.registry) return current; current = cleanChildren(parent, current, marker); } else if (t === 'function') { wrap(() => current = insertExpression(parent, value(), current, marker)); + } else if (Array.isArray(value)) { const array = normalizeIncomingArray([], value); + if (config.hydrate && config.hydrate.registry) return current; if (array.length === 0) { current = cleanChildren(parent, current, marker); if (multi) return current;