creo 0.0.2 → 0.0.4-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.development +1 -0
- package/.github/workflows/main.yml +24 -0
- package/README.md +1 -52
- package/TODOS.md +2 -0
- package/index.html +13 -0
- package/index.ts +1 -0
- package/package.json +12 -44
- package/src/DOM/Context.ts +36 -0
- package/src/DOM/DomEngine.ts +106 -0
- package/src/DOM/IRenderCycle.ts +9 -0
- package/src/DOM/Key.ts +1 -0
- package/src/DOM/Node.ts +472 -0
- package/src/DOM/Registry.ts +53 -0
- package/src/creo.ts +134 -0
- package/src/data-structures/assert/assert.ts +12 -0
- package/src/data-structures/indexed-map/IndexedMap.ts +281 -0
- package/src/data-structures/linked-map/LinkedMap.spec.ts +67 -0
- package/src/data-structures/linked-map/LinkedMap.ts +198 -0
- package/src/data-structures/list/List.spec.ts +181 -0
- package/src/data-structures/list/List.ts +195 -0
- package/src/data-structures/maybe/Maybe.ts +25 -0
- package/src/data-structures/null/null.ts +3 -0
- package/src/data-structures/record/IsRecordLike.spec.ts +29 -0
- package/src/data-structures/record/IsRecordLike.ts +3 -0
- package/src/data-structures/record/Record.spec.ts +240 -0
- package/src/data-structures/record/Record.ts +145 -0
- package/src/data-structures/shalllowEqual/shallowEqual.ts +26 -0
- package/src/data-structures/simpleKey/simpleKey.ts +8 -0
- package/src/data-structures/wildcard/wildcard.ts +1 -0
- package/src/examples/SimpleTodoList/SimpleTodoList.ts +53 -0
- package/src/examples/simple.ts +0 -0
- package/src/globals.d.ts +1 -0
- package/src/main.ts +24 -0
- package/src/style.css +41 -0
- package/src/ui/html/Block.ts +10 -0
- package/src/ui/html/Button.ts +12 -0
- package/src/ui/html/HStack.ts +10 -0
- package/src/ui/html/Inline.ts +12 -0
- package/src/ui/html/List.ts +10 -0
- package/src/ui/html/Text.ts +9 -0
- package/src/ui/html/VStack.ts +11 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +23 -0
- package/vite.config.js +10 -0
- package/LICENSE +0 -21
- package/dist/index.cjs +0 -54
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts +0 -19
- package/dist/index.js +0 -51
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -51
- package/dist/index.mjs.map +0 -1
- package/dist/index.umd.js +0 -61
- package/dist/index.umd.js.map +0 -1
package/.env.development
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__DEV__=true
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
on:
|
|
3
|
+
pull_request:
|
|
4
|
+
branches:
|
|
5
|
+
- main
|
|
6
|
+
push:
|
|
7
|
+
branches:
|
|
8
|
+
- main
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
build:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- name: Use bun
|
|
17
|
+
uses: oven-sh/setup-bun@v2
|
|
18
|
+
|
|
19
|
+
- name: install and tests
|
|
20
|
+
run: |
|
|
21
|
+
bun install
|
|
22
|
+
bun test
|
|
23
|
+
env:
|
|
24
|
+
CI: true
|
package/README.md
CHANGED
|
@@ -1,52 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
TypeScript implementation maybe monad.
|
|
4
|
-
|
|
5
|
-
1. Easy-to-use
|
|
6
|
-
2. Small (267 Bytes)!
|
|
7
|
-
3. Typed API
|
|
8
|
-
|
|
9
|
-
## Install:
|
|
10
|
-
|
|
11
|
-
```shell
|
|
12
|
-
npm i @duorun/maybe --save
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## Playground:
|
|
16
|
-
|
|
17
|
-
Sandbox: https://codesandbox.io/p/sandbox/nifty-lake-5wpq2y
|
|
18
|
-
|
|
19
|
-
## Usages
|
|
20
|
-
|
|
21
|
-
Value is defined:
|
|
22
|
-
|
|
23
|
-
```js
|
|
24
|
-
just("bar"); // Maybe<string>
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Value is empty:
|
|
28
|
-
|
|
29
|
-
```js
|
|
30
|
-
none(); // Maybe<never>
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
Note: null / undefeind can be valid data:
|
|
34
|
-
|
|
35
|
-
```js
|
|
36
|
-
just(null); // Maybe<null>
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Check if value is defined:
|
|
40
|
-
|
|
41
|
-
```js
|
|
42
|
-
import { isNone } from "@duorun/maybe";
|
|
43
|
-
|
|
44
|
-
function test(maybe: Maybe<string>) {
|
|
45
|
-
if (isNone(maybe)) {
|
|
46
|
-
// maybe is None
|
|
47
|
-
} else {
|
|
48
|
-
// maybe is just
|
|
49
|
-
maybe.value; // string
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
```
|
|
1
|
+
Work in progress, stay tuned
|
package/TODOS.md
ADDED
package/index.html
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Vite + TS</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="app"></div>
|
|
11
|
+
<script type="module" src="/src/main.ts"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
package/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log("Hello via Bun!");
|
package/package.json
CHANGED
|
@@ -1,52 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "creo",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "Simple and typed Maybe monad",
|
|
3
|
+
"version": "0.0.4-dev",
|
|
5
4
|
"type": "module",
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"umd:main": "dist/index.umd.js",
|
|
11
|
-
"exports": {
|
|
12
|
-
".": {
|
|
13
|
-
"types": "./dist/index.d.ts",
|
|
14
|
-
"module": "./dist/index.module.js",
|
|
15
|
-
"import": "./dist/index.mjs",
|
|
16
|
-
"require": "./dist/index.js"
|
|
17
|
-
},
|
|
18
|
-
"./package.json": "./package.json"
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "vite",
|
|
7
|
+
"build": "tsc && vite build",
|
|
8
|
+
"preview": "vite preview"
|
|
19
9
|
},
|
|
20
|
-
"sideEffects": false,
|
|
21
10
|
"devDependencies": {
|
|
22
|
-
"
|
|
11
|
+
"typescript": "^5.2.2",
|
|
12
|
+
"vite": "^5.2.0",
|
|
23
13
|
"bun-types": "latest",
|
|
24
|
-
"
|
|
25
|
-
},
|
|
26
|
-
"peerDependencies": {
|
|
27
|
-
"typescript": "^5.0.0"
|
|
28
|
-
},
|
|
29
|
-
"repository": {
|
|
30
|
-
"type": "git",
|
|
31
|
-
"url": "git+ssh://git@github.com/xnimorz/maybe.git"
|
|
32
|
-
},
|
|
33
|
-
"browserslist": ["last 2 years", "node >= 12"],
|
|
34
|
-
"author": "Nik (nik@xnim.me)",
|
|
35
|
-
"license": "MIT",
|
|
36
|
-
"files": ["dist"],
|
|
37
|
-
"bugs": {
|
|
38
|
-
"url": "https://github.com/xnimorz/maybe/issues"
|
|
39
|
-
},
|
|
40
|
-
"homepage": "https://github.com/xnimorz/maybe#readme",
|
|
41
|
-
"keywords": ["monad", "maybe", "ts-maybe"],
|
|
42
|
-
"scripts": {
|
|
43
|
-
"build": "microbundle build --entry ./index.ts --name @duorun/maybe --tsconfig tsconfig.json --compress false & bun run size-limit",
|
|
44
|
-
"prepublishOnly": "bun test & bun run build"
|
|
14
|
+
"@types/bun": "latest"
|
|
45
15
|
},
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
]
|
|
16
|
+
"module": "index.ts",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"csstype": "^3.1.3"
|
|
19
|
+
}
|
|
52
20
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Maybe } from "../data-structures/maybe/Maybe";
|
|
2
|
+
import {
|
|
3
|
+
onDidUpdate,
|
|
4
|
+
record,
|
|
5
|
+
RecordOf,
|
|
6
|
+
} from "../data-structures/record/Record";
|
|
7
|
+
import { Node } from "./Node";
|
|
8
|
+
|
|
9
|
+
export class Context<P> {
|
|
10
|
+
private subscribers: Array<() => void> = [];
|
|
11
|
+
private node: Node;
|
|
12
|
+
tracked = <T extends {}>(t: T): RecordOf<T> => {
|
|
13
|
+
const rec = record(t);
|
|
14
|
+
this.subscribers.push(
|
|
15
|
+
onDidUpdate(rec, () => {
|
|
16
|
+
this.node.invalidate();
|
|
17
|
+
}),
|
|
18
|
+
);
|
|
19
|
+
return rec;
|
|
20
|
+
};
|
|
21
|
+
p: P;
|
|
22
|
+
slot: Maybe<() => void>;
|
|
23
|
+
|
|
24
|
+
constructor(node: Node, initialParams: P, slot: Maybe<() => void>) {
|
|
25
|
+
this.node = node;
|
|
26
|
+
this.p = initialParams;
|
|
27
|
+
this.slot = slot;
|
|
28
|
+
}
|
|
29
|
+
dispose() {
|
|
30
|
+
this.subscribers.forEach((unsubscribe) => unsubscribe());
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
setSlot(slot: () => void): void {
|
|
34
|
+
this.slot = slot;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layout engine abstract class
|
|
3
|
+
*
|
|
4
|
+
*
|
|
5
|
+
* Ideas:
|
|
6
|
+
* [ ] Event systems
|
|
7
|
+
* [ ] Animation engine
|
|
8
|
+
*/
|
|
9
|
+
import { Maybe } from "../data-structures/maybe/Maybe";
|
|
10
|
+
import { IRenderCycle } from "./IRenderCycle";
|
|
11
|
+
import { Node, RootNode } from "./Node";
|
|
12
|
+
import { Registry } from "./Registry";
|
|
13
|
+
|
|
14
|
+
let $activeEngine: Maybe<DomEngine>;
|
|
15
|
+
|
|
16
|
+
export class DomEngine implements IRenderCycle {
|
|
17
|
+
protected isRerenderingScheduled = true;
|
|
18
|
+
// Queue of currently rendering items
|
|
19
|
+
protected registry: Registry = new Registry();
|
|
20
|
+
protected root!: RootNode;
|
|
21
|
+
protected rootHtml: HTMLElement;
|
|
22
|
+
|
|
23
|
+
constructor(root: HTMLElement) {
|
|
24
|
+
this.rootHtml = root;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public newNode(node: Node) {
|
|
28
|
+
this.registry.newNode(node);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public willRender(node: Node) {
|
|
32
|
+
this.registry.willRender(node);
|
|
33
|
+
this.scheduleRerender();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public isRendering(node: Node) {
|
|
37
|
+
this.registry.isRendering(node);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public didRender(node: Node): { justMounted: boolean } {
|
|
41
|
+
const result = this.registry.didRender(node);
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public dispose(node: Node) {
|
|
46
|
+
this.registry.dispose(node);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
debugStatus() {
|
|
50
|
+
console.log(this.registry);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
render(renderFn: () => void): void {
|
|
54
|
+
if (this.root != null) {
|
|
55
|
+
return this.forceRerender();
|
|
56
|
+
}
|
|
57
|
+
this.root = new RootNode(this.rootHtml, renderFn, this);
|
|
58
|
+
this.forceRerender();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
forceRerender(): void {
|
|
62
|
+
if (this.root == null) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
console.log("forcererender");
|
|
66
|
+
this.willRender(this.root);
|
|
67
|
+
this.rerender();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
scheduleRerender(): void {
|
|
71
|
+
if (this.isRerenderingScheduled) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
this.isRerenderingScheduled = true;
|
|
75
|
+
globalThis.requestAnimationFrame(() => {
|
|
76
|
+
this.rerender();
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
protected renderNextPending() {
|
|
81
|
+
this.isRerenderingScheduled = false;
|
|
82
|
+
const next = this.registry.getNextToRender();
|
|
83
|
+
if (next != null) {
|
|
84
|
+
next.render();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
getParent(): Maybe<Node> {
|
|
89
|
+
return this.registry.getNextRendering();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
rerender() {
|
|
93
|
+
$activeEngine = this;
|
|
94
|
+
this.renderNextPending();
|
|
95
|
+
$activeEngine = null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
shouldUpdateNode(node: Node): boolean {
|
|
99
|
+
return this.registry.shouldUpdateNode(node);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// TODO enhance with other engines, use DOMEngine for now
|
|
104
|
+
export function getActiveEngine(): Maybe<DomEngine> {
|
|
105
|
+
return $activeEngine;
|
|
106
|
+
}
|
package/src/DOM/Key.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Key = number | string;
|