creo 0.2.5 → 0.2.7
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/AGENTS.md +156 -0
- package/CHANGELOG.md +138 -0
- package/README.md +4 -2
- package/dist/functional/key.d.ts +0 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +293 -146
- package/dist/index.js.map +15 -15
- package/dist/internal/internal_view.d.ts +10 -1
- package/dist/public/primitive.d.ts +9 -10
- package/dist/public/primitives/primitives.d.ts +341 -111
- package/dist/public/state.d.ts +6 -0
- package/dist/public/view.d.ts +27 -12
- package/dist/render/html_render.d.ts +8 -0
- package/dist/render/render_interface.d.ts +14 -0
- package/dist/render/string_render.d.ts +0 -2
- package/docs/create-app.md +110 -0
- package/docs/events.md +236 -0
- package/docs/getting-started.md +201 -0
- package/docs/how-to/data-fetching.md +155 -0
- package/docs/how-to/deploy-vercel.md +130 -0
- package/docs/how-to/router.md +111 -0
- package/docs/how-to/styles.md +124 -0
- package/docs/how-to/suspense.md +116 -0
- package/docs/index.md +66 -0
- package/docs/lifecycle.md +173 -0
- package/docs/primitives.md +195 -0
- package/docs/renderers.md +183 -0
- package/docs/state.md +131 -0
- package/docs/store.md +135 -0
- package/docs/view.md +205 -0
- package/package.json +5 -2
- package/dist/public/event_handle.d.ts +0 -32
- package/dist/render/canvas_render.d.ts +0 -1
- package/dist/render/stream_render.d.ts +0 -1
- package/dist/structures/indexed_list.d.ts +0 -46
- package/dist/structures/list.d.ts +0 -68
package/docs/store.md
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Store
|
|
2
|
+
|
|
3
|
+
Creo's store system provides globally visible reactive data. A store is created outside views and can be read/written from any view via `use()`.
|
|
4
|
+
|
|
5
|
+
## Creating a store
|
|
6
|
+
|
|
7
|
+
Use `store.new(initial)` at module scope:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { store } from "creo";
|
|
11
|
+
|
|
12
|
+
const ThemeStore = store.new<"light" | "dark">("light");
|
|
13
|
+
const UserStore = store.new<{ name: string; role: string } | null>(null);
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Store instances are typically defined at module scope and imported where needed.
|
|
17
|
+
|
|
18
|
+
## Reading from a view
|
|
19
|
+
|
|
20
|
+
Use `use(store)` inside a view function to subscribe and get a reactive accessor:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { view, div, text } from "creo";
|
|
24
|
+
|
|
25
|
+
const ThemedButton = view(({ use }) => {
|
|
26
|
+
const theme = use(ThemeStore); // re-renders when ThemeStore changes
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
render() {
|
|
30
|
+
button({ class: theme.get() === "dark" ? "btn-dark" : "btn-light" }, () => {
|
|
31
|
+
text("Click me");
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`use(store)` subscribes the view to changes. When the store value is updated via `.set()` or `.update()`, all subscribed views are scheduled for re-render. Subscriptions are automatically cleaned up when the view is disposed.
|
|
39
|
+
|
|
40
|
+
## Setting values
|
|
41
|
+
|
|
42
|
+
Call `.set()` or `.update()` on the store directly -- from anywhere, including outside views:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
// From a handler
|
|
46
|
+
const toggle = () => {
|
|
47
|
+
const current = ThemeStore.get();
|
|
48
|
+
ThemeStore.set(current === "light" ? "dark" : "light");
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// From outside any view
|
|
52
|
+
ThemeStore.set("dark");
|
|
53
|
+
|
|
54
|
+
// Using update
|
|
55
|
+
ThemeStore.update(current => current === "light" ? "dark" : "light");
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Complete example
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import { createApp, store, view, div, button, span, text, HtmlRender } from "creo";
|
|
62
|
+
|
|
63
|
+
// 1. Create the store
|
|
64
|
+
const CounterStore = store.new(0);
|
|
65
|
+
|
|
66
|
+
// 2. Writer component
|
|
67
|
+
const IncrementButton = view(({ use }) => {
|
|
68
|
+
const counter = use(CounterStore);
|
|
69
|
+
const increment = () => counter.update(n => n + 1);
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
render() {
|
|
73
|
+
button({ on: { click: increment } }, () => { text("+1"); });
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// 3. Reader component
|
|
79
|
+
const DisplayCount = view(({ use }) => {
|
|
80
|
+
const counter = use(CounterStore);
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
render() {
|
|
84
|
+
span({}, () => {
|
|
85
|
+
text(`Count: ${counter.get()}`);
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// 4. App
|
|
92
|
+
const App = view(() => ({
|
|
93
|
+
render() {
|
|
94
|
+
div({}, () => {
|
|
95
|
+
IncrementButton();
|
|
96
|
+
DisplayCount();
|
|
97
|
+
});
|
|
98
|
+
},
|
|
99
|
+
}));
|
|
100
|
+
|
|
101
|
+
// 5. Mount
|
|
102
|
+
createApp(() => App(), new HtmlRender(document.getElementById("app")!)).mount();
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Store vs State
|
|
106
|
+
|
|
107
|
+
Both store and local state use the same `use()` function and return the same `Reactive<T>` interface (`get`, `set`, `update`). The difference:
|
|
108
|
+
|
|
109
|
+
| | Store | State |
|
|
110
|
+
|---|---|---|
|
|
111
|
+
| Created with | `store.new(initial)` | `use(initial)` inside a view |
|
|
112
|
+
| Scope | Global -- shared across views | Local -- private to the view |
|
|
113
|
+
| Setting from outside | `MyStore.set(value)` | Not possible |
|
|
114
|
+
| Subscribes view | Yes -- `use(store)` re-renders on change | Yes -- `use(value)` re-renders on change |
|
|
115
|
+
|
|
116
|
+
## Store type
|
|
117
|
+
|
|
118
|
+
The `Store<T>` class is exported for type annotations:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import type { Store } from "creo";
|
|
122
|
+
|
|
123
|
+
function resetStore<T>(s: Store<T>, value: T): void {
|
|
124
|
+
s.set(value);
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Full API
|
|
129
|
+
|
|
130
|
+
| Method | Description |
|
|
131
|
+
|--------|-------------|
|
|
132
|
+
| `.get(): T` | Read the current value |
|
|
133
|
+
| `.set(value: T): void` | Set a new value, re-render all subscribers |
|
|
134
|
+
| `.update(fn: (current: T) => T): void` | Apply a sync transform, re-render subscribers |
|
|
135
|
+
| `.update(fn: (current: T) => Promise<T>): void` | Apply an async transform, re-render on resolve |
|
package/docs/view.md
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# view()
|
|
2
|
+
|
|
3
|
+
`view()` is the core API for defining components in Creo.
|
|
4
|
+
|
|
5
|
+
## Signature
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
function view<Props = void, Api = void>(
|
|
9
|
+
viewFn: ViewFn<Props, Api>
|
|
10
|
+
): (props: Props & { key?: Key }, slot?: Slot) => void;
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
When `Props` is `void` (no props), the returned function can be called with no arguments:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
const App = view((ctx) => ({
|
|
17
|
+
render() { /* ... */ },
|
|
18
|
+
}));
|
|
19
|
+
|
|
20
|
+
App(); // no args needed
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## ViewFn and context
|
|
24
|
+
|
|
25
|
+
The function passed to `view()` receives a **context object** (`ctx`) with three fields:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
const MyComponent = view<{ title: string }>((ctx) => {
|
|
29
|
+
// ctx.props -- function that returns the current props object
|
|
30
|
+
// ctx.use -- factory to create reactive state or subscribe to stores
|
|
31
|
+
// ctx.children -- pre-collected PendingView[] from the parent slot
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
render() { /* ... */ },
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### ctx.props
|
|
40
|
+
|
|
41
|
+
A function that returns the current props passed by the parent. Call `ctx.props()` to read:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
const Label = view<{ text: string }>((ctx) => ({
|
|
45
|
+
render() {
|
|
46
|
+
span({}, () => { text(ctx.props().text); });
|
|
47
|
+
},
|
|
48
|
+
}));
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Because `props` is a function, calling it always returns the latest values -- whether inside `render()`, lifecycle hooks, or event handlers:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
const Good = view<{ title: string }>((ctx) => ({
|
|
55
|
+
render() { text(ctx.props().title); }, // always current
|
|
56
|
+
}));
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### ctx.use
|
|
60
|
+
|
|
61
|
+
A factory function to create reactive state or subscribe to stores. See [State](./state.md) and [Store](./store.md).
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
const count = ctx.use(0); // Reactive<number> — local state
|
|
65
|
+
const items = ctx.use<string[]>([]); // Reactive<string[]> — local state
|
|
66
|
+
const theme = ctx.use(ThemeStore); // Reactive<string> — store subscription
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### ctx.children
|
|
70
|
+
|
|
71
|
+
An array of `PendingView` objects representing the children passed by the caller's slot. Pass `ctx.children` directly to a primitive's second argument to render them:
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
const Wrapper = view((ctx) => ({
|
|
75
|
+
render() {
|
|
76
|
+
div({ class: "wrapper" }, ctx.children);
|
|
77
|
+
},
|
|
78
|
+
}));
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
If the caller provided no slot, `ctx.children` is an empty array.
|
|
82
|
+
|
|
83
|
+
## ViewBody
|
|
84
|
+
|
|
85
|
+
The viewFn must return a `ViewBody` object. The only required field is `render`:
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
type ViewBody<Props, Api> = {
|
|
89
|
+
render: () => void;
|
|
90
|
+
mount?: {
|
|
91
|
+
before?: () => void;
|
|
92
|
+
after?: () => void;
|
|
93
|
+
};
|
|
94
|
+
update?: {
|
|
95
|
+
should?: (nextProps: Props) => boolean;
|
|
96
|
+
before?: () => void;
|
|
97
|
+
after?: () => void;
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
When `Api` is provided (not `void`), ViewBody also includes an `api` field. See [Exposing an API](#exposing-an-api) below.
|
|
103
|
+
|
|
104
|
+
### render()
|
|
105
|
+
|
|
106
|
+
Called on every render cycle. Inside `render()`, call primitives and child components imperatively. The order of calls defines the virtual DOM structure:
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
render() {
|
|
110
|
+
div({ class: "header" }, () => {
|
|
111
|
+
h1({}, () => { text("Title"); });
|
|
112
|
+
});
|
|
113
|
+
div({ class: "body" }, () => {
|
|
114
|
+
text("Content");
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
All standard JavaScript control flow works inside render:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
render() {
|
|
123
|
+
if (isEditing.get()) {
|
|
124
|
+
input({ value: draft.get(), on: { input: handleInput } });
|
|
125
|
+
} else {
|
|
126
|
+
span({}, () => { text(value.get()); });
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
for (const item of items.get()) {
|
|
130
|
+
ListItem({ key: item.id, data: item });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Lifecycle hooks
|
|
136
|
+
|
|
137
|
+
See [Lifecycle](./lifecycle.md) for details on `mount` and `update`.
|
|
138
|
+
|
|
139
|
+
## Calling components
|
|
140
|
+
|
|
141
|
+
Components are called as functions. The first argument is props, the second is an optional slot:
|
|
142
|
+
|
|
143
|
+
```ts
|
|
144
|
+
// No props, no children
|
|
145
|
+
MyComponent();
|
|
146
|
+
|
|
147
|
+
// With props
|
|
148
|
+
Counter({ initial: 5 });
|
|
149
|
+
|
|
150
|
+
// With children (slot)
|
|
151
|
+
Card({}, () => {
|
|
152
|
+
text("Inside the card");
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// With props and children
|
|
156
|
+
Section({ title: "Info" }, () => {
|
|
157
|
+
Paragraph({ text: "Details here" });
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Keys
|
|
162
|
+
|
|
163
|
+
Pass `key` in the props object to help reconciliation identify items across re-renders:
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
for (const user of users.get()) {
|
|
167
|
+
UserCard({ key: user.id, name: user.name });
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Exposing an API via `ref`
|
|
172
|
+
|
|
173
|
+
Both primitives and composite views accept a `ref` prop on the call site, and
|
|
174
|
+
both fill it through the same `Ref<T>` machinery. The difference is on the
|
|
175
|
+
provider side: the renderer pushes the DOM `Element` into a primitive's ref;
|
|
176
|
+
inside a composite, you push an API object yourself by calling `ctx.ref(...)`.
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
import { view, type RefObject } from "creo";
|
|
180
|
+
|
|
181
|
+
const TextInput = view<{ placeholder: string }, { focus: () => void }>(
|
|
182
|
+
({ props, ref }) => {
|
|
183
|
+
const inputRef: RefObject<HTMLInputElement> = { current: null };
|
|
184
|
+
ref({
|
|
185
|
+
focus: () => inputRef.current?.focus(),
|
|
186
|
+
});
|
|
187
|
+
return {
|
|
188
|
+
render() {
|
|
189
|
+
input({ placeholder: props().placeholder, ref: inputRef });
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
},
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
// Consumer:
|
|
196
|
+
const myInput: RefObject<{ focus: () => void }> = { current: null };
|
|
197
|
+
TextInput({ placeholder: "Email", ref: myInput });
|
|
198
|
+
// After mount:
|
|
199
|
+
myInput.current?.focus();
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
`ref` works the same on primitives — `div({ ref })` populates `.current` (or
|
|
203
|
+
fires the callback) with the underlying `Element` after mount, and `null` on
|
|
204
|
+
unmount. The provider verb is `ctx.ref(...)` on a composite; the consumer
|
|
205
|
+
noun is `ref` in props on either side.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "creo",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -12,7 +12,10 @@
|
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"files": [
|
|
15
|
-
"dist"
|
|
15
|
+
"dist",
|
|
16
|
+
"AGENTS.md",
|
|
17
|
+
"CHANGELOG.md",
|
|
18
|
+
"docs"
|
|
16
19
|
],
|
|
17
20
|
"scripts": {
|
|
18
21
|
"build": "bun run build.ts",
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { Wildcard } from "../internal/wildcard";
|
|
2
|
-
type EventCallback = (...args: Wildcard[]) => void;
|
|
3
|
-
/**
|
|
4
|
-
* Delegate that the renderer provides to wire event subscriptions
|
|
5
|
-
* to the actual output (DOM addEventListener, etc.).
|
|
6
|
-
* Set on the EventHandle after the view's output is created.
|
|
7
|
-
*/
|
|
8
|
-
export type EventDelegate = {
|
|
9
|
-
bind(event: string, callback: EventCallback, once?: boolean): void;
|
|
10
|
-
unbind(event: string, callback: EventCallback): void;
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
* Handle returned when calling a primitive in the render stream.
|
|
14
|
-
* Provides on/once/off for event subscription.
|
|
15
|
-
*
|
|
16
|
-
* When a delegate is set (by the renderer after mount), calls are
|
|
17
|
-
* proxied to the renderer — only events the user subscribes to
|
|
18
|
-
* get bound. Before the delegate exists, listeners are stored and
|
|
19
|
-
* flushed once the delegate arrives.
|
|
20
|
-
*/
|
|
21
|
-
export declare class EventHandle<Events> {
|
|
22
|
-
#private;
|
|
23
|
-
on<K extends keyof Events>(event: K, callback: Events[K]): void;
|
|
24
|
-
once<K extends keyof Events>(event: K, callback: Events[K]): void;
|
|
25
|
-
off<K extends keyof Events>(event: K, callback: Events[K]): void;
|
|
26
|
-
/**
|
|
27
|
-
* Called by the renderer after the view's output is created.
|
|
28
|
-
* Flushes any listeners that were added before the delegate existed.
|
|
29
|
-
*/
|
|
30
|
-
setDelegate(delegate: EventDelegate): void;
|
|
31
|
-
}
|
|
32
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* IndexedList — linked list with O(1) identity-based lookup.
|
|
3
|
-
*
|
|
4
|
-
* Combines a doubly-linked list (O(1) insert/delete given a node)
|
|
5
|
-
* with a Map<T, INode<T>> for O(1) lookup by value identity.
|
|
6
|
-
*
|
|
7
|
-
* All mutating operations are O(1):
|
|
8
|
-
* push, delete, has, first, last, clear
|
|
9
|
-
*/
|
|
10
|
-
import { type INode } from "./list";
|
|
11
|
-
import type { Maybe } from "../functional/maybe";
|
|
12
|
-
export declare class IndexedList<T> {
|
|
13
|
-
#private;
|
|
14
|
-
/** Append item to the end. No-op if already present. Returns the node. */
|
|
15
|
-
push(item: T): INode<T>;
|
|
16
|
-
/** Insert item at the front. No-op if already present. */
|
|
17
|
-
unshift(item: T): void;
|
|
18
|
-
/** Insert item after ref. No-op if item already present. */
|
|
19
|
-
insertAfter(ref: T, item: T): void;
|
|
20
|
-
/** Remove item. O(1). */
|
|
21
|
-
delete(item: T): void;
|
|
22
|
-
/** Check membership. O(1). */
|
|
23
|
-
has(item: T): boolean;
|
|
24
|
-
/** Number of items. */
|
|
25
|
-
get length(): number;
|
|
26
|
-
/** Get the first item (head). O(1). */
|
|
27
|
-
first(): Maybe<T>;
|
|
28
|
-
/** Get the last item (tail). O(1). */
|
|
29
|
-
last(): Maybe<T>;
|
|
30
|
-
/** Get the linked-list node for an item. O(1). */
|
|
31
|
-
getNode(item: T): Maybe<INode<T>>;
|
|
32
|
-
/** Positional access. O(n) — prefer getNode + getNext for traversal. */
|
|
33
|
-
at(index: number): Maybe<T>;
|
|
34
|
-
/**
|
|
35
|
-
* Replace item at `pos`, or insert if nothing is there.
|
|
36
|
-
* If `pos >= length`, appends to the end.
|
|
37
|
-
* Returns the node.
|
|
38
|
-
*/
|
|
39
|
-
upsert(pos: number, item: T): INode<T>;
|
|
40
|
-
/** Swap two items in the list. O(1). No-op if either item is missing. */
|
|
41
|
-
swap(a: T, b: T): void;
|
|
42
|
-
/** Reset to empty. O(1). */
|
|
43
|
-
clear(): void;
|
|
44
|
-
/** Iterate values in insertion order. */
|
|
45
|
-
[Symbol.iterator](): IterableIterator<T>;
|
|
46
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Linked list implementation
|
|
3
|
-
*/
|
|
4
|
-
import type { Maybe } from "../functional/maybe";
|
|
5
|
-
declare const $next: unique symbol;
|
|
6
|
-
declare const $prev: unique symbol;
|
|
7
|
-
declare const $owner: unique symbol;
|
|
8
|
-
export interface INode<T> {
|
|
9
|
-
insertNext(value: T): INode<T>;
|
|
10
|
-
insertPrev(value: T): INode<T>;
|
|
11
|
-
v: T;
|
|
12
|
-
delete(): void;
|
|
13
|
-
getNext(): Maybe<INode<T>>;
|
|
14
|
-
getPrev(): Maybe<INode<T>>;
|
|
15
|
-
isFirst(): boolean;
|
|
16
|
-
isLast(): boolean;
|
|
17
|
-
}
|
|
18
|
-
export declare class ListNode<T> implements INode<T> {
|
|
19
|
-
[$owner]: Maybe<IBaseContainer<T>>;
|
|
20
|
-
[$next]: Maybe<ListNode<T>>;
|
|
21
|
-
[$prev]: Maybe<ListNode<T>>;
|
|
22
|
-
v: T;
|
|
23
|
-
constructor(node: T, prev: Maybe<ListNode<T>>, next: Maybe<ListNode<T>>, list: IBaseContainer<T>);
|
|
24
|
-
isFirst(): boolean;
|
|
25
|
-
isLast(): boolean;
|
|
26
|
-
delete(): void;
|
|
27
|
-
clearFields(): void;
|
|
28
|
-
insertNext(value: T): INode<T>;
|
|
29
|
-
insertPrev(value: T): INode<T>;
|
|
30
|
-
getNext(): Maybe<ListNode<T>>;
|
|
31
|
-
getPrev(): Maybe<ListNode<T>>;
|
|
32
|
-
getList(): Maybe<IBaseContainer<T>>;
|
|
33
|
-
}
|
|
34
|
-
interface IBaseContainer<T> {
|
|
35
|
-
delete(node: INode<T>): void;
|
|
36
|
-
insertNext(ref: INode<T>, value: T): INode<T>;
|
|
37
|
-
insertPrev(ref: INode<T>, value: T): INode<T>;
|
|
38
|
-
}
|
|
39
|
-
export interface IList<T> extends Iterable<INode<T>>, IBaseContainer<T> {
|
|
40
|
-
insertStart(value: T): INode<T>;
|
|
41
|
-
insertEnd(value: T): INode<T>;
|
|
42
|
-
at(n: number): Maybe<INode<T>>;
|
|
43
|
-
first(): Maybe<INode<T>>;
|
|
44
|
-
last(): Maybe<INode<T>>;
|
|
45
|
-
readonly size: number;
|
|
46
|
-
[Symbol.iterator](): IterableIterator<INode<T>>;
|
|
47
|
-
}
|
|
48
|
-
export declare class InternalList<T> implements IList<T> {
|
|
49
|
-
#private;
|
|
50
|
-
insertStart(value: T): ListNode<T>;
|
|
51
|
-
delete(node: INode<T>): void;
|
|
52
|
-
at(n: number): Maybe<ListNode<T>>;
|
|
53
|
-
get size(): number;
|
|
54
|
-
/** Reset the list to empty. O(1). */
|
|
55
|
-
clear(): void;
|
|
56
|
-
/** O(1) head access. */
|
|
57
|
-
first(): Maybe<ListNode<T>>;
|
|
58
|
-
/** O(1) tail access. */
|
|
59
|
-
last(): Maybe<ListNode<T>>;
|
|
60
|
-
insertEnd(value: T): ListNode<T>;
|
|
61
|
-
insertNext(ref: INode<T>, value: T): ListNode<T>;
|
|
62
|
-
insertPrev(ref: INode<T>, value: T): ListNode<T>;
|
|
63
|
-
[Symbol.iterator](): Generator<ListNode<T>, void, unknown>;
|
|
64
|
-
}
|
|
65
|
-
export declare class List<T> extends InternalList<T> implements IList<T> {
|
|
66
|
-
static from<T>(arrayLike: Iterable<T>): List<T>;
|
|
67
|
-
}
|
|
68
|
-
export {};
|