From 26f12e0a8f6c8460876d337d0ec417836a0a21f4 Mon Sep 17 00:00:00 2001 From: CoolElectronics Date: Sun, 31 Dec 2023 22:01:48 -0500 Subject: [PATCH] add code --- .gitignore | 3 + .npmignore | 2 + AliceJS.d.ts | 23 +++ AliceJS.js | 466 ++++++++++++++++++++++++++++++++++++++++++ LICENSE | 7 + README.md | 86 ++++++++ examples/example.html | 18 ++ examples/index.css | 14 ++ examples/index.tsx | 41 ++++ package.json | 24 +++ pnpm-lock.yaml | 259 +++++++++++++++++++++++ tsconfig.json | 29 +++ 12 files changed, 972 insertions(+) create mode 100644 .gitignore create mode 100644 .npmignore create mode 100644 AliceJS.d.ts create mode 100644 AliceJS.js create mode 100644 LICENSE create mode 100644 README.md create mode 100644 examples/example.html create mode 100644 examples/index.css create mode 100644 examples/index.tsx create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f00f5fa --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +examples/lib/ +dist/* +node_modules diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..c14a397 --- /dev/null +++ b/.npmignore @@ -0,0 +1,2 @@ +examples/ +node_modules diff --git a/AliceJS.d.ts b/AliceJS.d.ts new file mode 100644 index 0000000..0ac09d1 --- /dev/null +++ b/AliceJS.d.ts @@ -0,0 +1,23 @@ +declare namespace JSX { + export type IntrinsicElements = { [index: string]: any }; +} + +declare function h( + type: string, + props: { [index: string]: any } | null, + ...children: (HTMLElement | string)[] +): Node; + +type AliceJSReferenceSink = { readonly __symbol: unique symbol }; + +declare function use(sink: any, mapping?: (...args: any[]) => any): AliceJSReferenceSink; + +type Stateful = T & { readonly symbol: unique symbol }; + + +declare function stateful(target: T): Stateful; + +declare function handle(references: AliceJSReferenceSink, callback: (value: any) => void): void; + +declare function css(strings: TemplateStringsArray, ...values: any): string; +declare var styled: { new: typeof css }; diff --git a/AliceJS.js b/AliceJS.js new file mode 100644 index 0000000..4504879 --- /dev/null +++ b/AliceJS.js @@ -0,0 +1,466 @@ +// The global list of "references", as captured by the proxy in stateful +let __reference_stack = []; + +// We add some extra properties into various objects throughout, better to use symbols and not interfere +let ALICEJS_REFERENCES_MAPPING = Symbol(); +let ALICEJS_REFERENCES_MARKER = Symbol(); +let ALICEJS_STATEFUL_LISTENERS = Symbol(); + +// Say you have some code like +//// let state = stateful({ +//// a: 1 +//// }) +//// let elm =

{window.use(state.a)}

+// +// According to the standard, the order of events is as follows: +// - the getter for window.use gets called, setting __reference_stack to an empty list +// - the proxy for state.a is triggered, pushing { state, "a", Proxy(state) } onto __reference_stack +// - the function that the getter returns is called, popping everything off the stack +// - the JSX factory h() is now passed the *reference* of state.a, not the value +Object.defineProperty(window, "use", { + get: () => { + __reference_stack = []; + return (_sink, mapping) => { + let references = __reference_stack; + __reference_stack = []; + + references[ALICEJS_REFERENCES_MARKER] = true; + if (mapping) references[ALICEJS_REFERENCES_MAPPING] = mapping; + return references; + }; + } +}); +Object.assign(window, { h, stateful, handle, css, styled: { new: css } }); + +// This wraps the target in a proxy, doing 2 things: +// - whenever a property is accessed, update the reference stack +// - whenever a property is set, notify the subscribed listeners +// This is what makes our "pass-by-reference" magic work +export function stateful(target) { + target[ALICEJS_STATEFUL_LISTENERS] = []; + + const proxy = new Proxy(target, { + get(target, property, proxy) { + __reference_stack.push({ target, property, proxy }); + return Reflect.get(target, property, proxy); + }, + set(target, property, val) { + for (const listener of target[ALICEJS_STATEFUL_LISTENERS]) { + listener(target, property, val); + } + return Reflect.set(target, property, val); + }, + }); + + return proxy; +} + +function isAJSReferences(arr) { + return arr instanceof Array && ALICEJS_REFERENCES_MARKER in arr +} + +// This lets you subscribe to a stateful object +export function handle(references, callback) { + if (!isAJSReferences(references)) + throw new Error("Not an AliceJS reference set!"); + + if (ALICEJS_REFERENCES_MAPPING in references) { + const mapping = references[ALICEJS_REFERENCES_MAPPING]; + const used_props = []; + const used_targets = []; + + const values = new Map(); + + const pairs = []; + + const partial_update = (target, prop, val) => { + if (used_props.includes(prop) && used_targets.includes(target)) { + values.get(target)[prop] = val; + } + }; + + const full_update = () => { + const flattened_values = pairs.map( + (pair) => values.get(pair[0])[pair[1]], + ); + + const value = mapping(...flattened_values); + + callback(value); + }; + + for (const p of references) { + const target = p.target; + const prop = p.property; + + used_props.push(prop); + used_targets.push(target); + + pairs.push([target, prop]); + + if (!values.has(target)) { + values.set(target, {}); + } + + partial_update(target, prop, target[prop]); + + target[ALICEJS_STATEFUL_LISTENERS].push((t, p, v) => { + partial_update(t, p, v); + full_update(); + }); + } + full_update(); + } else { + const reference = references[references.length - 1]; + const subscription = (target, prop, val) => { + if (prop === reference.property && target === reference.target) { + callback(val); + } + }; + reference.target[ALICEJS_STATEFUL_LISTENERS].push(subscription); + subscription(reference.target, reference.property, reference.target[reference.property]); + } +} + +// Actual JSX factory. Responsible for creating the HTML elements and all of the *reactive* syntactic sugar +export function h(type, props, ...children) { + if (typeof type === "function") { + let newthis = stateful({}); + let component = type.bind(newthis); + + return component(); + } + + + const elm = document.createElement(type); + + function addChild(child) { + + if (isAJSReferences(child)) { + let appended = []; + handle(child, (val) => { + if (appended.length > 1) { + // this is why we don't encourage arrays (jank) + appended.forEach(n => n.remove()); + appended = addChild(val); + } else if (appended.length > 0) { + appended[0].replaceWith((appended = addChild(val))[0]); + } else { + appended = addChild(val); + } + }); + } else if (child instanceof Node) { + elm.appendChild(child); + return [child]; + } else if (child instanceof Array) { + let elms = []; + for (const childchild of child) { + elms = elms.concat(addChild(childchild)); + } + return elms; + } else { + let node = document.createTextNode(child); + elm.appendChild(node); + return [node]; + } + } + + for (const child of children) { + addChild(child); + } + + if (!props) return elm; + + function useProp(name, callback) { + if (!(name in props)) return; + let prop = props[name]; + callback(prop); + delete props[name]; + } + + // insert an element at the start + useProp("before", callback => { + addChild(callback()); + }) + + useProp("css", classname => { + elm.classList.add(classname); + elm.classList.add("self"); + }); + + + // if/then/else syntax + useProp("if", condition => { + let thenblock = props["then"]; + let elseblock = props["else"]; + + if (isAJSReferences(condition)) { + if (thenblock) elm.appendChild(thenblock); + if (elseblock) elm.appendChild(elseblock); + + handle(condition, val => { + if (thenblock) { + if (val) { + thenblock.style.display = ""; + if (elseblock) elseblock.style.display = "none"; + } else { + thenblock.style.display = "none"; + + if (elseblock) elseblock.style.display = ""; + } + } else { + if (val) { + elm.style.display = ""; + } else { + elm.style.display = "none"; + } + } + }); + } else { + if (thenblock) { + if (condition) { + elm.appendChild(thenblock); + } else if (elseblock) { + elm.appendChild(elseblock); + } + } else { + if (condition) { + elm.appendChild(thenblock); + } else if (elseblock) { + elm.appendChild(elseblock); + } else { + elm.style.display = "none"; + return document.createTextNode(""); + } + } + } + + delete props["then"]; + delete props["else"]; + }); + + if ("for" in props && "do" in props) { + const predicate = props["for"]; + const closure = props["do"]; + + if (isAJSReferences(predicate)) { + const __elms = []; + let lastpredicate = []; + handle(predicate, val => { + if ( + Object.keys(val).length && + Object.keys(val).length == lastpredicate.length + ) { + let i = 0; + for (const index in val) { + if ( + deepEqual(val[index], lastpredicate[index]) + ) { + continue; + } + const part = closure(val[index], index, val); + elm.replaceChild(part, __elms[i]); + __elms[i] = part; + + i += 1; + } + lastpredicate = Object.keys( + JSON.parse(JSON.stringify(val)), + ); + } else { + for (const part of __elms) { + part.remove(); + } + for (const index in val) { + const value = val[index]; + + const part = closure(value, index, val); + if (part instanceof HTMLElement) { + __elms.push(part); + elm.appendChild(part); + } + } + + lastpredicate = []; + } + }); + } else { + for (const index in predicate) { + const value = predicate[index]; + + const part = closure(value, index, predicate); + if (part instanceof Node) elm.appendChild(part); + + } + } + + delete props["for"]; + delete props["do"]; + } + + + // two-way bind an + useProp("$value", references => { + if (!isAJSReferences(references)) return; + if (!(elm instanceof HTMLInputElement)) return; + + handle(references, value => elm.value = value); + let reference = references[references.length - 1]; + elm.addEventListener("change", () => { + reference.proxy[reference.property] = elm.value; + }) + }); + + // insert an element at the end + useProp("after", callback => { + addChild(callback()); + }) + + // apply the non-reactive properties + for (const name in props) { + const prop = props[name]; + if (isAJSReferences(prop)) { + handle(prop, (val) => { + JSXAddAttributes(elm, name, val); + }); + } else { + JSXAddAttributes(elm, name, prop); + } + } + + return elm; +} + + +// Where properties are assigned to elements, and where the *non-reactive* syntax sugar goes +function JSXAddAttributes(elm, name, prop) { + if (name === "class") { + elm.className = prop; + return; + } + + if (typeof prop === "function" && name === "@mount") { + prop(elm); + return; + } + + if (typeof prop === "function" && name.startsWith("#")) { + const names = name.substring(1); + for (const name of names.split("$")) { + elm.addEventListener(name, (...args) => { + window.$el = elm; + prop(...args); + }); + } + return; + } + + if (typeof prop === "function" && name.startsWith("observe")) { + const observerclass = window[`${name.substring(8)}Observer`]; + if (!observerclass) { + console.error(`Observer ${name} does not exist`); + return; + } + const observer = new observerclass(entries => { + for (const entry of entries) { + window.$el = elm; + prop(entry); + } + }); + observer.observe(elm); + return; + } + if (name.startsWith("bind:")) { + const propname = name.substring(5); + prop[propname] = elm; + return; + } + + elm.setAttribute(name, prop); +} +function parse_css(uid, css) { + let cssParsed = ""; + + const virtualDoc = document.implementation.createHTMLDocument(""); + const virtualStyleElement = document.createElement("style"); + + virtualStyleElement.textContent = css; + virtualDoc.body.appendChild(virtualStyleElement); + + //@ts-ignore + for (const rule of virtualStyleElement.sheet.cssRules) { + rule.selectorText = rule.selectorText.includes("self") + ? `.${uid}.self${rule.selectorText.replace("self", "")}` + : `.${uid} ${rule.selectorText}`; + cssParsed += `${rule.cssText}\n`; + } + + return cssParsed; +} +export function css(strings, ...values) { + const uid = `alicecss-${Array(16) + .fill(0) + .map(() => { + return Math.floor(Math.random() * 16).toString(16); + }) + .join("")}`; + + const styleElement = document.createElement("style"); + + document.head.appendChild(styleElement); + + const flattened_template = []; + for (const i in strings) { + flattened_template.push(strings[i]); + if (values[i]) { + const prop = values[i]; + + if (isAJSReferences(prop)) { + const current_i = flattened_template.length; + handle(prop, (val) => { + flattened_template[current_i] = String(val); + styleElement.textContent = parse_css( + uid, + flattened_template.join(""), + ); + }); + } else { + flattened_template.push(String(prop)); + } + } + } + + styleElement.textContent = parse_css( + uid, + flattened_template.join(""), + ); + + return uid; +} + +function deepEqual(object1, object2) { + const keys1 = Object.keys(object1); + const keys2 = Object.keys(object2); + + if (keys1.length !== keys2.length) { + return false; + } + + for (const key of keys1) { + const val1 = object1[key]; + const val2 = object2[key]; + const areObjects = isObject(val1) && isObject(val2); + if ( + (areObjects && !deepEqual(val1, val2)) || + (!areObjects && val1 !== val2) + ) { + return false; + } + } + + return true; +} + +function isObject(object) { + return object != null && typeof object === "object"; +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..302d902 --- /dev/null +++ b/LICENSE @@ -0,0 +1,7 @@ +Copyright 2024 Mercury Workshop + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..265c07d --- /dev/null +++ b/README.md @@ -0,0 +1,86 @@ +# AliceJS +A utilitarian rendering library + +## What is AliceJS +AliceJS is a reactive JSX-based library with **no virtual dom** + +## Why do we need another javascript framework???? +not sure to be honest + +## What does it look like? +Here's a simple counter app +```jsx +function App() { + this.counter = 0; + return ( +
+ +

+ Value: {use(this.counter)} +

+
+ ); +} + +window.addEventListener("load", () => { + document.body.appendChild(); +}); +``` + +Compare that to the equivalent code in react: +```jsx +import { React, useState } from 'react' + +function App() { + const [counter, setCounter] = useState(0); + + const increase = () => { + setCounter(count => count + 1); + }; + + return ( +
+ +

+ Value: {use(this.counter)} +

+
+ ); +} + +ReactDOM.render( + + + , + document.getElementById("root") +); +``` + +AliceJS provides a simple and intuitive API at a low cost + +To get started with AliceJS, add this to your `tsconfig.json` +```json +"jsx":"react", +"jsxFactory":"h", +"jsxFragmentFactory":"YOU_CANT_USE_FRAGMENTS", +"types": ["@MercuryWorkshop/AliceJS"], +``` +and run `npm install @mercuryworkshop/alicejs` + +If you prefer using modules and are using a bundler, simply `import "@mercuryworkshop/alicejs";` into at least one file you're using. + +If you don't like using modules, just add `` to your html, and you can use AliceJS as normal. + +AliceJS can even be used without a build step, here's the counter example in plain JS +```javascript +function Index() { + this.counter = 0; + return (h("div",{}, + h("button", { "#click": () => this.counter++ }, "Click me!"), + h("p",{}, "Value: ", use(this.counter)))); +} +window.addEventListener("load", () => { + document.body.appendChild(h(Index, null)); +}); +``` + diff --git a/examples/example.html b/examples/example.html new file mode 100644 index 0000000..ba8ec5e --- /dev/null +++ b/examples/example.html @@ -0,0 +1,18 @@ + + + + + AliceJS examples + + + + + + + + + + + + + diff --git a/examples/index.css b/examples/index.css new file mode 100644 index 0000000..16922cc --- /dev/null +++ b/examples/index.css @@ -0,0 +1,14 @@ +html,body { + padding: 0; + margin: 0; + width: 100vw; + height: 100vh; + + background-color: #191724; +} + +body { + display: flex; + justify-content: center; + align-items: center; +} diff --git a/examples/index.tsx b/examples/index.tsx new file mode 100644 index 0000000..8f78213 --- /dev/null +++ b/examples/index.tsx @@ -0,0 +1,41 @@ +function Index() { + let css = styled.new` + self { + background-color: #1f1d2e; + border-radius: 25px; + padding:2em; + } + + button { + border-radius: 25px; + } + + p,h1 { + font-family: "serif"; + color: #e0def4; + } + + p { + font-size:15px; + } +`; + + this.counter = 0; + + return ( +
+

AliceJS Examples

+ +

+ Value: {use(this.counter)} +

+

+ is {use(this.counter)} odd? {use(this.counter, p => p % 2 == 1)} +

+
+ ); +} + +window.addEventListener("load", () => { + document.body.appendChild(); +}); diff --git a/package.json b/package.json new file mode 100644 index 0000000..e08c7da --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": "@mercuryworkshop/alicejs", + "version": "1.0.0", + "description": "A utilitarian HTML rendering library", + "scripts": { + "build": "esbuild --minify --bundle AliceJS.js --outdir=dist && tsc", + "watch": "esbuild --watch=forever --bundle AliceJS.js --outdir=dist & tsc --watch" + }, + "keywords": ["html","jsx","framework","alicejs"], + "author": "MercuryWorkshop", + "repository": "https://github.com/MercuryWorkshop/AliceJS", + "license": "MIT", + "exports": { + ".": { + "browser": "./dist/index.js", + "node": "./dist/index.js", + "types":"./AliceJS.d.ts" + } + }, + "devDependencies": { + "esbuild": "^0.19.11", + "typescript": "^5.3.3" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..b624fb5 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,259 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +devDependencies: + esbuild: + specifier: ^0.19.11 + version: 0.19.11 + typescript: + specifier: ^5.3.3 + version: 5.3.3 + +packages: + + /@esbuild/aix-ppc64@0.19.11: + resolution: {integrity: sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64@0.19.11: + resolution: {integrity: sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.19.11: + resolution: {integrity: sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.19.11: + resolution: {integrity: sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.19.11: + resolution: {integrity: sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.19.11: + resolution: {integrity: sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.19.11: + resolution: {integrity: sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.19.11: + resolution: {integrity: sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.19.11: + resolution: {integrity: sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.19.11: + resolution: {integrity: sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.19.11: + resolution: {integrity: sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.19.11: + resolution: {integrity: sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.19.11: + resolution: {integrity: sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.19.11: + resolution: {integrity: sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.19.11: + resolution: {integrity: sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.19.11: + resolution: {integrity: sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.19.11: + resolution: {integrity: sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.19.11: + resolution: {integrity: sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.19.11: + resolution: {integrity: sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.19.11: + resolution: {integrity: sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.19.11: + resolution: {integrity: sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.19.11: + resolution: {integrity: sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.19.11: + resolution: {integrity: sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild@0.19.11: + resolution: {integrity: sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.19.11 + '@esbuild/android-arm': 0.19.11 + '@esbuild/android-arm64': 0.19.11 + '@esbuild/android-x64': 0.19.11 + '@esbuild/darwin-arm64': 0.19.11 + '@esbuild/darwin-x64': 0.19.11 + '@esbuild/freebsd-arm64': 0.19.11 + '@esbuild/freebsd-x64': 0.19.11 + '@esbuild/linux-arm': 0.19.11 + '@esbuild/linux-arm64': 0.19.11 + '@esbuild/linux-ia32': 0.19.11 + '@esbuild/linux-loong64': 0.19.11 + '@esbuild/linux-mips64el': 0.19.11 + '@esbuild/linux-ppc64': 0.19.11 + '@esbuild/linux-riscv64': 0.19.11 + '@esbuild/linux-s390x': 0.19.11 + '@esbuild/linux-x64': 0.19.11 + '@esbuild/netbsd-x64': 0.19.11 + '@esbuild/openbsd-x64': 0.19.11 + '@esbuild/sunos-x64': 0.19.11 + '@esbuild/win32-arm64': 0.19.11 + '@esbuild/win32-ia32': 0.19.11 + '@esbuild/win32-x64': 0.19.11 + dev: true + + /typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} + engines: {node: '>=14.17'} + hasBin: true + dev: true diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..8695227 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + + "lib": [ + "ESNext", + "dom" + ], + "outDir": "./examples/lib", + "removeComments": true, + "target": "ES6", + + "jsx":"react", + "jsxFactory":"h", + "jsxFragmentFactory":"YOU_CANT_USE_FRAGMENTS", + + "sourceMap": true, + "sourceRoot": "", + + "alwaysStrict": false, + "noImplicitAny": false, + "strictNullChecks":false, + + "noUncheckedIndexedAccess": true + }, + "include": ["./examples/*.ts","./examples/*.tsx", "./AliceJS.d.ts"], + "exclude": [ + "node_modules/**/*" + ] +}