{"id":21310959,"url":"https://github.com/webqit/quantum-js","last_synced_at":"2025-04-05T02:07:01.091Z","repository":{"id":38308852,"uuid":"307696162","full_name":"webqit/quantum-js","owner":"webqit","description":"A runtime extension to JavaScript that enables us do Imperative Reactive Programming (IRP) in the very language!","archived":false,"fork":false,"pushed_at":"2025-03-04T12:38:40.000Z","size":19445,"stargazers_count":85,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-29T01:12:55.216Z","etag":null,"topics":["estree","imperative-programming","imperative-reactive-programming","reactive-programming","reactivity","web-native","wicg","wicg-proposals"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/webqit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"ox-harris","patreon":null,"open_collective":"webqit","ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2020-10-27T12:42:46.000Z","updated_at":"2025-03-04T12:38:44.000Z","dependencies_parsed_at":"2023-07-14T01:27:35.338Z","dependency_job_id":"9e26bcce-5f0a-42c7-b90c-ab67a13fb5f6","html_url":"https://github.com/webqit/quantum-js","commit_stats":{"total_commits":640,"total_committers":4,"mean_commits":160.0,"dds":"0.11250000000000004","last_synced_commit":"3dadfdf4b07cfbfa4009a2aaf28490061897e272"},"previous_names":["webqit/contract","webqit/reflex-functions","webqit/subscript","web-native/subscript","webqit/stateful-js","webqit/quantum-js"],"tags_count":215,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webqit%2Fquantum-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webqit%2Fquantum-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webqit%2Fquantum-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/webqit%2Fquantum-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/webqit","download_url":"https://codeload.github.com/webqit/quantum-js/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247076866,"owners_count":20879754,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["estree","imperative-programming","imperative-reactive-programming","reactive-programming","reactivity","web-native","wicg","wicg-proposals"],"created_at":"2024-11-21T17:15:21.687Z","updated_at":"2025-04-05T02:07:01.060Z","avatar_url":"https://github.com/webqit.png","language":"JavaScript","funding_links":["https://github.com/sponsors/ox-harris","https://opencollective.com/webqit"],"categories":[],"sub_categories":[],"readme":"# Quantum JS\n\n[![npm version][npm-version-src]][npm-version-href]\u003c!--[![npm downloads][npm-downloads-src]][npm-downloads-href]--\u003e\n[![bundle][bundle-src]][bundle-href]\n[![License][license-src]][license-href]\n\n[Overview](#overview) • [Creating Quantum Programs](#creating-quantum-programs) • [Implementation](#implementation) • [Examples](#examples) • [License](#license)\n\nQuantum JS is a runtime extension to JavaScript that brings Imperative Reactive Programming to JavaScript!\n\nWhat's that?\n\n## Overview\n \nWhere you normally would require certain reactive primitives to express reactive logic...\n\n```js\n// Import reactive primitives\nimport { createSignal, createMemo, createEffect } from 'solid-js';\n\n// Declare values\nconst [ count, setCount ] = createSignal(5);\nconst doubleCount = createMemo(() =\u003e count() * 2);\n// Log this value live\ncreateEffect(() =\u003e {\n  console.log(doubleCount());\n});\n```\n\n```js\n// Setup periodic updates\nsetInterval(() =\u003e setCount(10), 1000);\n```\n\nQuantum JS lets you acheive the same in the ordinary imperative form of the language:\n\n```js\n// Declare values\nlet count = 5;\nlet doubleCount = count * 2;\n// Log this value live\nconsole.log(doubleCount);\n```\n\n```js\n// Setup periodic updates\nsetInterval(() =\u003e count = 10, 1000);\n```\n\nWanna play?:\n\n1. Add the following script to your page:\n\n  ```html\n  \u003cscript src=\"https://unpkg.com/@webqit/oohtml/dist/main.js\"\u003e\u003c/script\u003e\n  ```\n\n2. Write your logic within a `quantum` script tag:\n\n  ```html\n  \u003cscript quantum\u003e\n    // Declare values\n    let count = 5;\n    let doubleCount = count * 2;\n    // Log this value live\n    console.log(doubleCount);\n\n    // Setup periodic updates\n    setInterval(() =\u003e count = 10, 1000);\n  \u003c/script\u003e\n  ```\n\n3. Watch your console. Have fun.\n\nWanna see how magical things really are here? Update your step 2 to split the logic into two separate scripts:\n\n2. One ordinary script and one quantum script:\n\n  ```html\n  \u003cscript\u003e // An ordinary script; no probelm\n    // Declare values\n    let count = 5;\n    let doubleCount = count * 2;\n    // Setup periodic updates\n    setInterval(() =\u003e count = 10, 1000);\n  \u003c/script\u003e\n  ```\n\n  ```html\n  \u003cscript quantum\u003e // A quantum script; for live mode\n    // Log this value live\n    console.log(doubleCount);\n  \u003c/script\u003e\n  ```\n\nWatching your console? Reactivity is still intact!\n\nThat reactivity is really happening within the Quantum script! It's a regular script in every way except that any peice of code thrown in is able to statically reflect changes to state in granular details!\n\nTo define, Quantum programs are an extension to JavaScript that has any piece of code stay sensitive to changes in the most fine-grained details - and entirely with no moving parts!\n\nNow, while that is the `\u003cscript quantum\u003e\u003c/script\u003e` part of the HTML page above, there are many different ways to have this form of reactivity play out. Examples are [just ahead](#examples).\n\nThis project pursues a futuristic, more efficient way to write reactive applocations *today*! And it occupies [a new category](https://en.wikipedia.org/wiki/Reactive_programming#Imperative) in the reactivity spectrum!\n\n\u003c!--\n## Idea\n\n\u003cdetails\u003e\u003csummary\u003eShow\u003c/summary\u003e\n\nImperative programs are really the foundation for \"state\", \"effect\" and much of what we try to model today at an abstract level using, sometimes, functional reactive primitives as above, and sometimes some other means to the same end. Now, that's really us _re-implementing existing machine-level concepts_ that should be best left to the machine!\n\n\u003cdetails\u003e\u003csummary\u003eLearn more\u003c/summary\u003e\n\nRight in how the instructions in an imperative program \"act\" on data - from the assignment expression that sets or changes the data held in a local variable (`count = 10`) to the `delete` operator that mutates some object property (`delete object.value`), to the \"if\" construct that determines the program's execution path based on a certain state - we can see all of \"state\" (data), \"effect\" (instructions that modify state/data), and control structures (instructions informed by state, in turn) at play!\n\nBut what we don't get with how this works naturally is having the said instructions stay sensitive to changes to the data they individually act on! (The runtime simply not maintaining that relationship!) And that's where the problem lies; where a whole new way of doing things becomes necessary - wherein we have to approach literal operations programmatically: `setCount(10)` vs `count = 10`.\n\n\u003c/details\u003e\n\nIf we could get the JS runtime to add \"reactivity\" to how it already works - i.e. having the very instructions stay sensitive to changes to the data they individually act on - we absolutely would be enabling reactive programming in the imperative form of the language and entirely unnecessitating the manual way!\n\nThis is what we're exploring with Quantum JS!\n\n└ You may want to learn more in the introductory article: [Re-Exploring Reactivity and Introducing the Observer API and Reflex Functions](https://dev.to/oxharris/re-exploring-reactivity-and-introducing-the-observer-api-and-reflex-functions-4h70)\n\n\u003c/details\u003e\n\n## Status\n\n+ Actively maintained\n+ A working implementation\n+ Integral to the [OOHTML project](https://github.com/webqit/oohtml)\n+ Open to contributions\n\n--\u003e\n\n## Implementation\n\nAs seen above, you can have all of Quantum JS live in the browser!\n\nUp there, we've used a version of the Quantum JS implementation that supports HTML `\u003cscript\u003e` elements. That is the OOHTML polyfill ([OOHTML](https://github.com/webqit/oohtml)) and it's the most direct way to use Quantum JS in your web app.\n\nBelow are the standard Quantum JS polyfills - for when you aren't writing HTML `\u003cscript\u003e` elements. The design is such that you can easily use these as part of your tooling or compile process; e.g. to have Quantum JS as compile target.\n\n\u003cdetails\u003e\u003csummary\u003eLoad from a CDN\u003cbr\u003e\n└───────── \u003ca href=\"https://bundlephobia.com/result?p=@webqit/quantum-js\"\u003e\u003cimg align=\"right\" src=\"https://img.shields.io/bundlephobia/minzip/@webqit/quantum-js?label=\u0026style=flat\u0026colorB=black\"\u003e\u003c/a\u003e\u003c/summary\u003e\n\n```html\n\u003cscript src=\"https://unpkg.com/@webqit/quantum-js/dist/main.js\"\u003e\u003c/script\u003e\n```\n\n└ This is to be placed early on in the document and should be a classic script without any `defer` or `async` directives!\n\n```js\n// Destructure from the webqit namespace\nconst { QuantumFunction, AsyncQuantumFunction, QuantumScript, QuantumModule, State, Observer } = window.webqit;\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003eInstall from NPM\u003cbr\u003e\n└───────── \u003ca href=\"https://npmjs.com/package/@webqit/quantum-js\"\u003e\u003cimg align=\"right\" src=\"https://img.shields.io/npm/v/@webqit/quantum-js?style=flat\u0026label=\u0026colorB=black\"\u003e\u003c/a\u003e\u003c/summary\u003e\n\n```js\n// npm install\nnpm i @webqit/quantum-js\n```\n\n```js\n// Import API\nimport { QuantumFunction, AsyncQuantumFunction, QuantumScript, AsyncQuantumScript, QuantumModule, State, Observer } from '@webqit/quantum-js';\n```\n\n\u003c/details\u003e\n\n\u003c/details\u003e\n\n### Quantum JS Lite\n\nIt is possible to use a lighter version of Quantum JS where you want something further feather weight for your initial application load.\n\n\u003cdetails\u003e\u003csummary\u003e\nLoad from a CDN\u003cbr\u003e\n└───────── \u003ca href=\"https://bundlephobia.com/result?p=@webqit/quantum-js\"\u003e\u003cimg align=\"right\" src=\"https://img.shields.io/badge/10.8%20kB-black\"\u003e\u003c/a\u003e\u003c/summary\u003e\n\n```html\n\u003cscript src=\"https://unpkg.com/@webqit/quantum-js/dist/main.lite.js\"\u003e\u003c/script\u003e\n```\n\n└ This is to be placed early on in the document and should be a classic script without any `defer` or `async` directives!\n\n```js\n// Destructure from the webqit namespace\nconst { AsyncQuantumFunction, AsyncQuantumScript, QuantumModule, State, Observer } = window.webqit;\n```\n\n\u003cdetails\u003e\u003csummary\u003eAdditional details\u003c/summary\u003e\n\nThe Lite APIs initially come without the compiler and yet lets you work with Quantum JS ahead of that. Additionally, these APIs are able to do their compilation off the main thread by getting the Quantum JS compiler loaded into a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers)!\n\n\u003e But if you may, the Quantum JS Compiler is all still loadable directly - as if short-circuiting the lazy-loading strategy of the Lite APIs:\n\u003e \n\u003e ```html\n\u003e \u003chead\u003e\n\u003e  \u003cscript src=\"https://unpkg.com/@webqit/quantum-js/dist/compiler.js\"\u003e\u003c/script\u003e \u003c!-- Must come before the polyfil --\u003e\n\u003e   \u003cscript src=\"https://unpkg.com/@webqit/quantum-js/dist/main.lite.js\"\u003e\u003c/script\u003e\n\u003e \u003c/head\u003e\n\u003e ```\n\n\u003c/details\u003e\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003eInstall from NPM\u003cbr\u003e\n└───────── \u003ca href=\"https://npmjs.com/package/@webqit/quantum-js\"\u003e\u003cimg align=\"right\" src=\"https://img.shields.io/npm/v/@webqit/quantum-js?style=flat\u0026label=\u0026colorB=black\"\u003e\u003c/a\u003e\u003c/summary\u003e\n\n```js\n// npm install\nnpm i @webqit/quantum-js\n```\n\n```js\n// Import Lite API\nimport { AsyncQuantumFunction, AsyncQuantumScript, QuantumModule, State, Observer } from '@webqit/quantum-js/lite';\n```\n\n\u003c/details\u003e\n\n## Creating Quantum Programs\n\nYou can write Quantum programs in either of two ways: as \"Quantum Functions\" and as \"Quantum Scripts\"!\n\n### Quantum Functions\n\nHere, we introduce a new type of function that works like any other JavaScript function but in reactive mode. This function may be wrtten in any of the forms below:\n\n#### Syntax 1: Using the `quantum` Function keyword\n\n\u003e Available since v4.3.\n\nHere you prepend your function with the `quantum` keyword, just in how you use the `async` keyword:\n\n```js\n// Quantum function declaration\nquantum function bar() {\n  let count = 5;\n  let doubleCount = count * 2;\n  console.log(doubleCount);\n}\nbar();\n```\n\n```js\n// Async quantum function declaration\nasync quantum function bar() {\n  let count = await 5;\n  let doubleCount = count * 2;\n  console.log(doubleCount);\n}\nawait bar();\n```\n\n\u003cdetails\u003e\u003csummary\u003eShow more syntax examples\u003c/summary\u003e\n\n```js\n// Quantum function expression\nconst bar = quantum function() {\n}\nconst bar = async quantum function() {\n}\n```\n\n```js\n// Quantum object property\nconst foo = {\n  bar: quantum function() { ... },\n}\nconst foo = {\n  bar: async quantum function() { ... },\n}\n```\n\n```js\n// Quantum object method\nconst foo = {\n  quantum bar() { ... },\n}\nconst foo = {\n  async quantum bar() { ... },\n}\n```\n\n```js\n// Quantum class method\nclass Foo {\n  quantum bar() { ... }\n}\nclass Foo {\n  async quantum bar() { ... }\n}\n```\n\n```js\n// Quantum arrow function expression\nconst bar = quantum () =\u003e {\n}\nconst bar = async quantum () =\u003e {\n}\n```\n\n```js\n// Quantum arrow function expression\nconst bar = quantum arg =\u003e {\n}\nconst bar = async quantum arg =\u003e {\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003eShow polyfill support\u003c/summary\u003e\n\nThis syntax is universally supported both within:\n\n+ Quantum JS' dynamic APIs:\n\n    ```js\n    const program = new QuantumFunction(`\n      // External dependency\n      let externalVar = 10;\n\n      // QuantumFunction\n      quantum function sum(a, b) {\n        return a + b + externalVar;\n      }\n      const state = sum(10, 10);\n\n      // Inspect\n      console.log(state.value); // 30\n    `);\n    program();\n    ```\n    \n+ and inline `\u003cscript\u003e` elements (as made possible by the [OOHTML Polyfill](https://github.com/webqit/oohtml)):\n\n    ```html\n    \u003cscript\u003e\n      // External dependency\n      let externalVar = 10;\n\n      // QuantumFunction\n      quantum function sum(a, b) {\n        return a + b + externalVar;\n      }\n      const state = sum(10, 10);\n\n      // Inspect\n      console.log(state.value); // 30\n    \u003c/script\u003e\n    ```\n\n\u003c/details\u003e\n \n#### Syntax 2: Using the Double Star `**` Notation\n\nHere you append your function with the double star `**` notation, much like how you write [generator functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator):\n\n```js\n// Quantum function declaration\nfunction** bar() {\n  let count = 5;\n  let doubleCount = count * 2;\n  console.log(doubleCount);\n}\nbar();\n```\n\n```js\n// Async quantum function declaration\nasync function** bar() {\n  let count = await 5;\n  let doubleCount = count * 2;\n  console.log(doubleCount);\n}\nawait bar();\n```\n\n\u003cdetails\u003e\u003csummary\u003eShow more syntax examples\u003c/summary\u003e\n\n```js\n// Quantum function expression\nconst bar = function** () {\n}\nconst bar = async function** () {\n}\n```\n\n```js\n// Quantum object property\nconst foo = {\n  bar: function** () { ... },\n}\nconst foo = {\n  bar: async function** () { ... },\n}\n```\n\n```js\n// Quantum object method\nconst foo = {\n  **bar() { ... },\n}\nconst foo = {\n  async **bar() { ... },\n}\n```\n\n```js\n// Quantum class method, optionally async\nclass Foo {\n  **bar() { ... }\n}\nclass Foo {\n  async **bar() { ... }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003eShow polyfill support\u003c/summary\u003e\n\nThis syntax is universally supported both within:\n\n+ Quantum JS' dynamic APIs:\n\n    ```js\n    const program = new QuantumFunction(`\n      // External dependency\n      let externalVar = 10;\n\n      // QuantumFunction\n      function** sum(a, b) {\n        return a + b + externalVar;\n      }\n      const state = sum(10, 10);\n\n      // Inspect\n      console.log(state.value); // 30\n    `);\n    program();\n    ```\n    \n+ and inline `\u003cscript\u003e` elements (as made possible by the [OOHTML Polyfill](https://github.com/webqit/oohtml)):\n\n    ```html\n    \u003cscript\u003e\n      // External dependency\n      let externalVar = 10;\n\n      // QuantumFunction\n      function** sum(a, b) {\n        return a + b + externalVar;\n      }\n      const state = sum(10, 10);\n\n      // Inspect\n      console.log(state.value); // 30\n    \u003c/script\u003e\n    ```\n\n\u003c/details\u003e\n\n#### Syntax 3: Using Quantum Function Constructors\n\nHere you use special function constructors to create a new Quantum function:\n\n```js\n// Quantum function constructor\nconst bar = QuantumFunction(`\n  let count = 5;\n  let doubleCount = count * 2;\n  console.log(doubleCount);\n`);\nbar();\n```\n\n```js\n// Async quantum function constructor\nconst bar = AsyncQuantumFunction(`\n  let count = await 5;\n  let doubleCount = count * 2;\n  console.log(doubleCount);\n`);\nawait bar();\n```\n\n\u003cdetails\u003e\u003csummary\u003eShow more syntax examples\u003c/summary\u003e\n\n```js\n// With function parameters\nconst bar = QuantumFunction( param1, ... paramN, functionBody );\n```\n\n```js\n// With the new keyword\nconst bar = new QuantumFunction( param1, ... paramN, functionBody );\n```\n\n```js\n// As class property\nclass Foo {\n  bar = QuantumFunction( param1, ... paramN, functionBody );\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003eShow polyfill support\u003c/summary\u003e\n\nThis is how you obtain the APIs:\n\n```js\n// Import API\nimport { QuantumFunction, AsyncQuantumFunction } from '@webqit/quantum-js';\n```\n\n```js\nconst { QuantumFunction, AsyncQuantumFunction } = window.webqit;\n```\n\nHere, the difference between `QuantumFunction` and `AsyncQuantumFunction` is same as the difference between a regular synchronous JS function (`function() {}`) and its *async* equivalent (`async function() {}`).\n\n```js\n// External dependency\nglobalThis.externalVar = 10;\n\n// QuantumFunction\nconst sum = QuantumFunction(`a`, `b`, `\n  return a + b + externalVar;\n`);\nconst state = sum(10, 10);\n\n// Inspect\nconsole.log(state.value); // 30\n```\n\n\u003e Note that, unlike the main Quantum JS build, the Quantum JS Lite edition only implements the `AsyncQuantumFunction` API which falls within the asynchronous operation of the Lite edition.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003eAdditional details\u003c/summary\u003e\n \nNote that unlike normal function declarations and expressions that can see their surrounding scope, as in syntaxes 1 and 2 above, code in [function constructors](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/Function) is only able to see the global scope:\n\n```js\nlet a;\nglobalThis.b = 2;\nvar c = 'c'; // Equivalent to globalThis.c = 'c' assuming that we aren't running in a function scope or module scope\nconst bar = QuantumFunction(`\n  console.log(typeof a); // undefined\n  console.log(typeof b); // number\n  console.log(typeof c); // string\n`);\nbar();\n```\n\n\u003c/details\u003e\n\n### Quantum Scripts (Whole Programs)\n\nHere, whole programs are able to run in *quantum* execution mode using special scripting APIs:\n\n```js\n// Quantum regular JS\nconst program = new QuantumScript(`\n  let count = 5;\n  let doubleCount = count * 2;\n  console.log(doubleCount);\n`);\nprogram.execute();\n```\n\n```js\n// Quantum module\nconst program = new QuantumModule(`\n  let count = await 5;\n  let doubleCount = count * 2;\n  console.log(doubleCount);\n`);\nawait program.execute();\n```\n\nThese will run in the global scope!\n\nThe latter does certainly let you use `import` and `export` statements!\n\n\u003cdetails\u003e\u003csummary\u003eExanple\u003c/summary\u003e\n\n```js\n// Quantum module\nconst program = new QuantumModule(`\n  import module1, { module2 } from 'package-name';\n  import { module3 as alias } from 'package-name';\n  ...\n  export * from 'package-name';\n  export let localVar = 0;\n`);\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003eShow polyfill support\u003c/summary\u003e\n\nThis is how you obtain the APIs:\n\n```js\n// Import API\nimport { QuantumScript, QuantumModule, AsyncQuantumScript } from '@webqit/quantum-js';\n```\n\n```js\nconst { QuantumScript, QuantumModule, AsyncQuantumScript } = window.webqit;\n```\n\nHere, the difference between `QuantumScript`, `AsyncQuantumScript`, and `QuantumModule` is same as the difference between a regular synchronous script element (`\u003cscript\u003e`), its *async* equivalent (`\u003cscript async\u003e`), and a module script (`\u003cscript type=\"module\"\u003e`).\n\n\u003e Note that, unlike the main Quantum JS build, the Quantum JS Lite edition only implements the `AsyncQuantumScript` and `QuantumModule` APIs which match the asynchronous nature of off the main thread compilation.\n\n\u003c/details\u003e\n\n## Consuming Quantum Programs\n\nEach call to a Quantum function or script returns back a `State` object that lets you consume the program from the outside. (This is similar to [what generator functions do](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator).)\n\nFor the Quantum functions above:\n\n```js\nconst state = bar();\n```\n\nFor the Quantum Script APIs above:\n\n```js\nconst state = program.execute();\n```\n\nFor Quantum HTML scripts - `\u003cscript quantum\u003e`, the `state` object is available as a direct property of the script element:\n\n```js\nconsole.log(script.state);\n```\n\n### Return Value\n\nThe `State` object features a `value` property that carries the program's actual return value:\n\n```js\nfunction** sum(a, b) {\n  return a + b;\n}\n```\n\n```js\nconst state = sum(5, 4);\nconsole.log(state.value); // 9\n```\n\nBut given a \"live\" program, the `state.value` property also comes as a \"live\" property that always reflects the program's new return value should anything make that change:\n\n```js\nfunction** counter() {\n  let count = 0\n  setInterval(() =\u003e count++, 500);\n  return count;\n}\n```\n\n```js\nconst state = counter();\nconsole.log(state.value); // 0\n```\n\nNow, the general-purpose, object-observability API: [Observer API](https://github.com/webqit/observer) puts those changes right in your hands:\n\n```js\nObserver.observe(state, 'value', mutation =\u003e {\n  //console.log(state.value); Or:\n  console.log(mutation.value); // 1, 2, 3, 4, etc.\n});\n```\n\n### Module Exports\n\nFor module programs, the `State` object also features an `exports` property that exposes the module's exports:\n\n```js\n// Quantum module\nconst program = new QuantumModule(`\n  import module1, { module2 } from 'package-name';\n  import { module3 as alias } from 'package-name';\n  ...\n  export * from 'package-name';\n  export let localVar = 0;\n`);\n```\n\n```js\nconst state = await program.execute();\nconsole.log(state.exports); // { module1, module2, module3, ..., localVar }\n```\n\nBut given a \"live\" program, each property in the `state.exports` object also comes as a \"live\" property that always reflects an export's new value should anything make that change:\n\n```js\n// As module\nconst program = new QuantumModule(`\n  export let localVar = 0;\n  ...\n  setInterval(() =\u003e localVar++, 500);\n`);\n```\n\n```js\nconst state = await program.execute();\nconsole.log(state.exports); // { localVar }\n```\n\nNow, again, the Observer API puts those changes right in your hands:\n\n```js\nObserver.observe(state.exports, 'localVar', mutation =\u003e {\n  //console.log(state.exports.localVar); Or:\n  console.log(mutation.value); // 1, 2, 3, 4, etc.\n});\n```\n\n```js\n// Observe \"any\" export\nObserver.observe(state.exports, mutations =\u003e {\n  mutations.forEach(mutation =\u003e console.log(mutation.key, mutation.value));\n});\n```\n\n## Disposing Quantum Programs\n\nQuantum programs may maintain many live relationships and should be disposed when their work is done! The `State` object they return exposes a `dispose()` method that lets us do just that:\n\n```js\nstate.dispose();\n```\n\nFor Quantum HTML Scripts - `\u003cscript quantum\u003e`,  state disposal is automatic as script element leaves the DOM!\n\n## Interaction with the Outside World\n\nQuantum programs can read and write to the given scope in which they run; just in how a regular JavaScript function can reference outside variables and also make side effects:\n\n```js\nlet a = 2, b;\nfunction** bar() {\n  b = a * 2;\n  console.log('Total:', b);\n}\nbar();\n```\n\nBut as an extension to regular JavaScript, Quantum programs maintain a live relationship with the outside world! This means that:\n\n### ...Updates Happening On the Outside Are Automatically Reflected\n\nGiven the code above, the following will now be reflected:\n\n```js\n// Update external dependency\na = 4;\n```\n\nThe above dependency and reactivity hold the same even if we had `a` in the place of a parameter's *default value*:\n\n```js\nlet a = 2, b = 0;\nfunction** bar(param = a) {\n  b = param * 2;\n  console.log('Total:', b);\n}\nbar();\n```\n\nAnd we get the same automatic dependency tracking with object properties:\n\n```js\n// External value\nconst obj = { a: 2, b: 0 };\n```\n\n```js\nfunction** bar() {\n  obj.b = obj.a * 2;\n  console.log('Total:', obj.b);\n}\nbar();\n```\n\n```js\n// Update external dependency\nobj.a = 4;\n```\n\n### ...Updates Happening On the Inside Are Observable\n\nGiven the same data binding principles, we are able to observe updates the other way round as to the updates made from the inside of the function: `b = 4`, `obj.b = 4`!\n\nFor updates to object properties, we're able to use the Observer API directly:\n\n```js\n// Observe changes to object properties\nconst obj = { a: 2, b: 0 };\nObserver.observe(obj, 'b', mutation =\u003e {\n  console.log('New value:', mutation.value);\n});\n```\n\nThe above holds the same also for global variables:\n\n```js\n// Observe changes to global variables\nb = 0; // globalThis.b = 0;\nObserver.observe(globalThis, 'b', mutation =\u003e {\n  console.log('New value:', mutation.value);\n});\n```\n\nAnd for updates to local variables, while we can't use the Observer API directly (as local variables aren't associated with a physical object as we have of global variables)...\n\n```js\nlet b = 0;\nObserver.observe(?, 'b', () =\u003e { ... });\n```\n\n...we're able to use a Quantion function itself to achieve the exact:\n\n```js\n(function** () {\n  console.log('New value:', b);\n})();\n```\n\n...and, where necessary, we could next map those changes to an object to use the Observer API there:\n\n```js\n(function** () {\n  obj.b = b;\n})();\nObserver.observe(obj, 'b', () =\u003e { ... });\n```\n\n## Detailed Documentation\n\nIn how Quantum programs are based on literal JavaScript, no special syntaxes exist around here! And the information covered here is entirely optional. (But you may find it interesting to deep dive.)\n\n+ [Reactivity](https://github.com/webqit/quantum-js/wiki#reactivity)\n+ [Sensitivity](https://github.com/webqit/quantum-js/wiki#sensitivity)\n+ [Update Model](https://github.com/webqit/quantum-js/wiki#update-model)\n+ [Flow Control](https://github.com/webqit/quantum-js/wiki#flow-control)\n+ [Experimental Features](https://github.com/webqit/quantum-js/wiki#experimental-features)\n\n## Examples\n\nUsing the Quantum JS and Observer API polyfills, the following examples work today. While we demonstrate the most basic forms of these scenarios, it takes roughly the same principles to build more intricate equivalents.\n\n\n\u003cdetails\u003e\u003csummary\u003eExample 1: \u003ci\u003eA Custom Element-Based Counter\u003c/i\u003e\u003cbr\u003e\n└───────── \u003c/summary\u003e\n\nIn this example, we demonstrate a custom element that works as a counter. Notice that the magic is in its Quantum `render()` method. Reactivity starts at *connected* time (on calling the `render()` method), and stops at *disconnected* time (on calling dispose)!\n\n```js\ncustomElements.define('click-counter', class extends HTMLElement {\n\n  count = 10;\n\n  connectedCallback() {\n    // Initial rendering\n    this._state = this.render();\n    // Static reflection at click time\n    this.addEventListener('click', () =\u003e {\n      this.count++;\n    });\n  }\n\n  disconnectCallback() {\n    // Cleanup\n    this._state.dispose();\n  }\n\n  // Using the QuantumFunction constructor\n  render = QuantumFunction(`\n    let countElement = this.querySelector('#count');\n    countElement.innerHTML = this.count;\n    \n    let doubleCount = this.count * 2;\n    let doubleCountElement = this.querySelector('#double-count');\n    doubleCountElement.innerHTML = doubleCount;\n    \n    let quadCount = doubleCount * 2;\n    let quadCountElement = this.querySelector('#quad-count');\n    quadCountElement.innerHTML = quadCount;\n  `);\n\n});\n```\n\n```html\n\u003cclick-counter style=\"display: block; padding: 1rem;\"\u003e\n  Click me\u003cbr\u003e\n  \u003cspan id=\"count\"\u003e\u003c/span\u003e\u003cbr\u003e\n  \u003cspan id=\"double-count\"\u003e\u003c/span\u003e\u003cbr\u003e\n  \u003cspan id=\"quad-count\"\u003e\u003c/span\u003e\n\u003c/click-counter\u003e\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003eExample 2: \u003ci\u003eA Custom \u003ccode\u003eURL\u003c/code\u003e API\u003c/i\u003e\u003cbr\u003e\n└───────── \u003c/summary\u003e\n\nIn this example, we demonstrate a simple replication of the [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL) API - where you have many interdependent properties! Notice that the magic is in its Quantum `compute()` method which is called from the constructor.\n\n```js\nconst MyURL = class {\n  constructor(href) {\n    // The raw url\n    this.href = href;\n    // Initial computations\n    this.compute();\n  }\n\n  compute = QuantumFunction(`\n    // These will be re-computed from this.href always\n    let { protocol, hostname, port, pathname, search, hash } = new URL(this.href);\n\n    this.protocol = protocol;\n    this.hostname = hostname;\n    this.port = port;\n    this.pathname = pathname;\n    this.search = search;\n    this.hash = hash;\n\n    // These individual property assignments each depend on the previous \n    this.host = this.hostname + (this.port ? ':' + this.port : '');\n    this.origin = this.protocol + '//' + this.host;\n    let href = this.origin + this.pathname + this.search + this.hash;\n    if (href !== this.href) { // Prevent unnecessary update\n      this.href = href;\n    }\n  `);\n}\n```\n\n```js\n// Instantiate\nconst url = new MyURL('https://www.example.com/path');\n\n// Change a property\nurl.protocol = 'http:'; //Observer.set(url, 'protocol', 'http:');\nconsole.log(url.href); // http://www.example.com/path\n\n// Change another\nurl.hostname = 'foo.dev'; //Observer.set(url, 'hostname', 'foo.dev');\nconsole.log(url.href); // http://foo.dev/path\n```\n\n\u003c/details\u003e\n\n## Getting Involved\n\nAll forms of contributions are welcome at this time. For example, syntax and other implementation details are all up for discussion. Also, help is needed with more formal documentation. And here are specific links:\n\n+ [Project](https://github.com/webqit/quantum-js)\n+ [Documentation](https://github.com/webqit/quantum-js/wiki)\n+ [Discusions](https://github.com/webqit/quantum-js/discussions)\n+ [Issues](https://github.com/webqit/quantum-js/issues)\n\n## License\n\nMIT.\n\n[npm-version-src]: https://img.shields.io/npm/v/@webqit/quantum-js?style=flat\u0026colorA=black\u0026colorB=F0DB4F\n[npm-version-href]: https://npmjs.com/package/@webqit/quantum-js\n[npm-downloads-src]: https://img.shields.io/npm/dm/@webqit/quantum-js?style=flat\u0026colorA=black\u0026colorB=F0DB4F\n[npm-downloads-href]: https://npmjs.com/package/@webqit/quantum-js\n[bundle-src]: https://img.shields.io/bundlephobia/minzip/@webqit/quantum-js?style=flat\u0026colorA=black\u0026colorB=F0DB4F\n[bundle-href]: https://bundlephobia.com/result?p=@webqit/quantum-js\n[license-src]: https://img.shields.io/github/license/webqit/quantum-js.svg?style=flat\u0026colorA=black\u0026colorB=F0DB4F\n[license-href]: https://github.com/webqit/quantum-js/blob/master/LICENSE\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebqit%2Fquantum-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwebqit%2Fquantum-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwebqit%2Fquantum-js/lists"}