ripple 0.1.1 → 0.2.0
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/LICENSE +21 -0
- package/package.json +56 -24
- package/src/ai.js +292 -0
- package/src/compiler/errors.js +26 -0
- package/src/compiler/index.js +26 -0
- package/src/compiler/phases/1-parse/index.js +543 -0
- package/src/compiler/phases/1-parse/style.js +566 -0
- package/src/compiler/phases/2-analyze/index.js +509 -0
- package/src/compiler/phases/2-analyze/prune.js +572 -0
- package/src/compiler/phases/3-transform/index.js +1572 -0
- package/src/compiler/phases/3-transform/segments.js +91 -0
- package/src/compiler/phases/3-transform/stylesheet.js +372 -0
- package/src/compiler/scope.js +421 -0
- package/src/compiler/utils.js +552 -0
- package/src/constants.js +4 -0
- package/src/jsx-runtime.d.ts +94 -0
- package/src/jsx-runtime.js +46 -0
- package/src/runtime/array.js +215 -0
- package/src/runtime/index.js +39 -0
- package/src/runtime/internal/client/blocks.js +247 -0
- package/src/runtime/internal/client/constants.js +23 -0
- package/src/runtime/internal/client/events.js +223 -0
- package/src/runtime/internal/client/for.js +388 -0
- package/src/runtime/internal/client/if.js +35 -0
- package/src/runtime/internal/client/index.js +53 -0
- package/src/runtime/internal/client/operations.js +72 -0
- package/src/runtime/internal/client/portal.js +33 -0
- package/src/runtime/internal/client/render.js +156 -0
- package/src/runtime/internal/client/runtime.js +909 -0
- package/src/runtime/internal/client/template.js +51 -0
- package/src/runtime/internal/client/try.js +139 -0
- package/src/runtime/internal/client/utils.js +16 -0
- package/src/utils/ast.js +214 -0
- package/src/utils/builders.js +733 -0
- package/src/utils/patterns.js +23 -0
- package/src/utils/sanitize_template_string.js +7 -0
- package/test-mappings.js +0 -0
- package/types/index.d.ts +2 -0
- package/.npmignore +0 -2
- package/History.md +0 -3
- package/Readme.md +0 -151
- package/lib/exec/index.js +0 -60
- package/ripple.js +0 -645
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { TEMPLATE_FRAGMENT, TEMPLATE_USE_IMPORT_NODE } from '../../../constants.js';
|
|
2
|
+
import { first_child, is_firefox } from './operations.js';
|
|
3
|
+
import { active_block } from './runtime.js';
|
|
4
|
+
|
|
5
|
+
export function assign_nodes(start, end) {
|
|
6
|
+
var block = /** @type {Effect} */ (active_block);
|
|
7
|
+
if (block.s === null) {
|
|
8
|
+
block.s = {
|
|
9
|
+
start,
|
|
10
|
+
end
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function create_fragment_from_html(html) {
|
|
16
|
+
var elem = document.createElement('template');
|
|
17
|
+
elem.innerHTML = html;
|
|
18
|
+
return elem.content;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function template(content, flags) {
|
|
22
|
+
var is_fragment = (flags & TEMPLATE_FRAGMENT) !== 0;
|
|
23
|
+
var use_import_node = (flags & TEMPLATE_USE_IMPORT_NODE) !== 0;
|
|
24
|
+
var node;
|
|
25
|
+
var has_start = !content.startsWith('<!>');
|
|
26
|
+
|
|
27
|
+
return () => {
|
|
28
|
+
if (node === undefined) {
|
|
29
|
+
node = create_fragment_from_html(has_start ? content : '<!>' + content);
|
|
30
|
+
if (!is_fragment) node = first_child(node);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
var clone =
|
|
34
|
+
use_import_node || is_firefox ? document.importNode(node, true) : node.cloneNode(true);
|
|
35
|
+
|
|
36
|
+
if (is_fragment) {
|
|
37
|
+
var start = first_child(clone);
|
|
38
|
+
var end = clone.lastChild;
|
|
39
|
+
|
|
40
|
+
assign_nodes(start, end);
|
|
41
|
+
} else {
|
|
42
|
+
assign_nodes(clone, clone);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return clone;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function append(anchor, dom) {
|
|
50
|
+
anchor.before(/** @type {Node} */ (dom));
|
|
51
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { branch, create_try_block, destroy_block, is_destroyed, resume_block } from './blocks';
|
|
2
|
+
import { TRY_BLOCK } from './constants';
|
|
3
|
+
import { next_sibling } from './operations';
|
|
4
|
+
import {
|
|
5
|
+
active_block,
|
|
6
|
+
active_component,
|
|
7
|
+
active_reaction,
|
|
8
|
+
queue_microtask,
|
|
9
|
+
set_active_block,
|
|
10
|
+
set_active_component,
|
|
11
|
+
set_active_reaction,
|
|
12
|
+
set_tracking,
|
|
13
|
+
tracking
|
|
14
|
+
} from './runtime';
|
|
15
|
+
|
|
16
|
+
export function try_block(node, fn, catch_fn, pending_fn = null) {
|
|
17
|
+
var anchor = node;
|
|
18
|
+
var b = null;
|
|
19
|
+
var suspended = null;
|
|
20
|
+
var pending_count = 0;
|
|
21
|
+
var offscreen_fragment = null;
|
|
22
|
+
|
|
23
|
+
function move_block(block, fragment) {
|
|
24
|
+
var state = block.s;
|
|
25
|
+
var node = state.start;
|
|
26
|
+
var end = state.end;
|
|
27
|
+
|
|
28
|
+
while (node !== null) {
|
|
29
|
+
var next = node === end ? null : next_sibling(node);
|
|
30
|
+
|
|
31
|
+
fragment.append(node);
|
|
32
|
+
node = next;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function handle_await() {
|
|
37
|
+
if (pending_count++ === 0) {
|
|
38
|
+
queue_microtask(() => {
|
|
39
|
+
if (b !== null) {
|
|
40
|
+
suspended = b;
|
|
41
|
+
offscreen_fragment = document.createDocumentFragment();
|
|
42
|
+
move_block(b, offscreen_fragment);
|
|
43
|
+
|
|
44
|
+
b = branch(() => {
|
|
45
|
+
pending_fn(anchor);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return () => {
|
|
52
|
+
if (--pending_count === 0) {
|
|
53
|
+
if (b !== null) {
|
|
54
|
+
destroy_block(b);
|
|
55
|
+
}
|
|
56
|
+
anchor.before(offscreen_fragment);
|
|
57
|
+
offscreen_fragment = null;
|
|
58
|
+
resume_block(suspended);
|
|
59
|
+
b = suspended;
|
|
60
|
+
suspended = null;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function handle_error(error) {
|
|
66
|
+
if (b !== null) {
|
|
67
|
+
destroy_block(b);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
b = branch(() => {
|
|
71
|
+
catch_fn(anchor, error);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
var state = {
|
|
76
|
+
a: pending_fn !== null ? handle_await : null,
|
|
77
|
+
c: catch_fn !== null ? handle_error : null
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
create_try_block(() => {
|
|
81
|
+
b = branch(() => {
|
|
82
|
+
fn(anchor);
|
|
83
|
+
});
|
|
84
|
+
}, state);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function suspend() {
|
|
88
|
+
var current = active_block;
|
|
89
|
+
|
|
90
|
+
while (current !== null) {
|
|
91
|
+
var state = current.s;
|
|
92
|
+
if ((current.f & TRY_BLOCK) !== 0 && state.a !== null) {
|
|
93
|
+
return state.a();
|
|
94
|
+
}
|
|
95
|
+
current = current.p;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
throw new Error('Missing parent `try { ... } async { ... }` statement');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function exit() {
|
|
102
|
+
set_tracking(false);
|
|
103
|
+
set_active_reaction(null);
|
|
104
|
+
set_active_block(null);
|
|
105
|
+
set_active_component(null);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function capture() {
|
|
109
|
+
var previous_tracking = tracking;
|
|
110
|
+
var previous_block = active_block;
|
|
111
|
+
var previous_reaction = active_reaction;
|
|
112
|
+
var previous_component = active_component;
|
|
113
|
+
|
|
114
|
+
return () => {
|
|
115
|
+
set_tracking(previous_tracking);
|
|
116
|
+
set_active_block(previous_block);
|
|
117
|
+
set_active_reaction(previous_reaction);
|
|
118
|
+
set_active_component(previous_component);
|
|
119
|
+
|
|
120
|
+
queue_microtask(exit);
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function aborted() {
|
|
125
|
+
if (active_block === null) {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
return is_destroyed(active_block);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export async function resume_context(promise) {
|
|
132
|
+
var restore = capture();
|
|
133
|
+
var value = await promise;
|
|
134
|
+
|
|
135
|
+
return () => {
|
|
136
|
+
restore();
|
|
137
|
+
return value;
|
|
138
|
+
};
|
|
139
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export var get_descriptor = Object.getOwnPropertyDescriptor;
|
|
2
|
+
export var get_descriptors = Object.getOwnPropertyDescriptors;
|
|
3
|
+
export var array_from = Array.from;
|
|
4
|
+
export var is_array = Array.isArray;
|
|
5
|
+
export var define_property = Object.defineProperty;
|
|
6
|
+
export var get_prototype_of = Object.getPrototypeOf;
|
|
7
|
+
export var object_values = Object.values;
|
|
8
|
+
export var object_entries = Object.entries;
|
|
9
|
+
export var object_keys = Object.keys;
|
|
10
|
+
export var structured_clone = structuredClone;
|
|
11
|
+
|
|
12
|
+
export function create_anchor() {
|
|
13
|
+
var t = document.createTextNode('');
|
|
14
|
+
t.__t = '';
|
|
15
|
+
return t;
|
|
16
|
+
}
|
package/src/utils/ast.js
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import * as b from './builders.js';
|
|
2
|
+
|
|
3
|
+
export function object(expression) {
|
|
4
|
+
while (expression.type === 'MemberExpression') {
|
|
5
|
+
expression = /** @type {ESTree.MemberExpression | ESTree.Identifier} */ (expression.object);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
if (expression.type !== 'Identifier') {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return expression;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function unwrap_pattern(pattern, nodes = []) {
|
|
16
|
+
switch (pattern.type) {
|
|
17
|
+
case 'Identifier':
|
|
18
|
+
nodes.push(pattern);
|
|
19
|
+
break;
|
|
20
|
+
|
|
21
|
+
case 'MemberExpression':
|
|
22
|
+
// member expressions can be part of an assignment pattern, but not a binding pattern
|
|
23
|
+
// see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#binding_and_assignment
|
|
24
|
+
nodes.push(pattern);
|
|
25
|
+
break;
|
|
26
|
+
|
|
27
|
+
case 'ObjectPattern':
|
|
28
|
+
for (const prop of pattern.properties) {
|
|
29
|
+
if (prop.type === 'RestElement') {
|
|
30
|
+
unwrap_pattern(prop.argument, nodes);
|
|
31
|
+
} else {
|
|
32
|
+
unwrap_pattern(prop.value, nodes);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
break;
|
|
37
|
+
|
|
38
|
+
case 'ArrayPattern':
|
|
39
|
+
for (const element of pattern.elements) {
|
|
40
|
+
if (element) unwrap_pattern(element, nodes);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
break;
|
|
44
|
+
|
|
45
|
+
case 'RestElement':
|
|
46
|
+
unwrap_pattern(pattern.argument, nodes);
|
|
47
|
+
break;
|
|
48
|
+
|
|
49
|
+
case 'AssignmentPattern':
|
|
50
|
+
unwrap_pattern(pattern.left, nodes);
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return nodes;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function extract_identifiers(pattern) {
|
|
58
|
+
return unwrap_pattern(pattern, []).filter((node) => node.type === 'Identifier');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function extract_paths(param) {
|
|
62
|
+
return _extract_paths(
|
|
63
|
+
[],
|
|
64
|
+
param,
|
|
65
|
+
(node) => /** @type {ESTree.Identifier | ESTree.MemberExpression} */ (node),
|
|
66
|
+
(node) => /** @type {ESTree.Identifier | ESTree.MemberExpression} */ (node),
|
|
67
|
+
false
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function _extract_paths(assignments = [], param, expression, update_expression, has_default_value) {
|
|
72
|
+
switch (param.type) {
|
|
73
|
+
case 'Identifier':
|
|
74
|
+
case 'MemberExpression':
|
|
75
|
+
assignments.push({
|
|
76
|
+
node: param,
|
|
77
|
+
is_rest: false,
|
|
78
|
+
has_default_value,
|
|
79
|
+
expression,
|
|
80
|
+
update_expression
|
|
81
|
+
});
|
|
82
|
+
break;
|
|
83
|
+
|
|
84
|
+
case 'ObjectPattern':
|
|
85
|
+
for (const prop of param.properties) {
|
|
86
|
+
if (prop.type === 'RestElement') {
|
|
87
|
+
/** @type {DestructuredAssignment['expression']} */
|
|
88
|
+
const rest_expression = (object) => {
|
|
89
|
+
/** @type {ESTree.Expression[]} */
|
|
90
|
+
const props = [];
|
|
91
|
+
|
|
92
|
+
for (const p of param.properties) {
|
|
93
|
+
if (p.type === 'Property' && p.key.type !== 'PrivateIdentifier') {
|
|
94
|
+
if (p.key.type === 'Identifier' && !p.computed) {
|
|
95
|
+
props.push(b.literal(p.key.name));
|
|
96
|
+
} else if (p.key.type === 'Literal') {
|
|
97
|
+
props.push(b.literal(String(p.key.value)));
|
|
98
|
+
} else {
|
|
99
|
+
props.push(b.call('String', p.key));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return b.call('$.exclude_from_object', expression(object), b.array(props));
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
if (prop.argument.type === 'Identifier') {
|
|
108
|
+
assignments.push({
|
|
109
|
+
node: prop.argument,
|
|
110
|
+
is_rest: true,
|
|
111
|
+
has_default_value,
|
|
112
|
+
expression: rest_expression,
|
|
113
|
+
update_expression: rest_expression
|
|
114
|
+
});
|
|
115
|
+
} else {
|
|
116
|
+
_extract_paths(
|
|
117
|
+
assignments,
|
|
118
|
+
prop.argument,
|
|
119
|
+
rest_expression,
|
|
120
|
+
rest_expression,
|
|
121
|
+
has_default_value
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
/** @type {DestructuredAssignment['expression']} */
|
|
126
|
+
const object_expression = (object) =>
|
|
127
|
+
b.member(expression(object), prop.key, prop.computed || prop.key.type !== 'Identifier');
|
|
128
|
+
_extract_paths(
|
|
129
|
+
assignments,
|
|
130
|
+
prop.value,
|
|
131
|
+
object_expression,
|
|
132
|
+
object_expression,
|
|
133
|
+
has_default_value
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
break;
|
|
139
|
+
|
|
140
|
+
case 'ArrayPattern':
|
|
141
|
+
for (let i = 0; i < param.elements.length; i += 1) {
|
|
142
|
+
const element = param.elements[i];
|
|
143
|
+
if (element) {
|
|
144
|
+
if (element.type === 'RestElement') {
|
|
145
|
+
/** @type {DestructuredAssignment['expression']} */
|
|
146
|
+
const rest_expression = (object) =>
|
|
147
|
+
b.call(b.member(expression(object), 'slice'), b.literal(i));
|
|
148
|
+
if (element.argument.type === 'Identifier') {
|
|
149
|
+
assignments.push({
|
|
150
|
+
node: element.argument,
|
|
151
|
+
is_rest: true,
|
|
152
|
+
has_default_value,
|
|
153
|
+
expression: rest_expression,
|
|
154
|
+
update_expression: rest_expression
|
|
155
|
+
});
|
|
156
|
+
} else {
|
|
157
|
+
_extract_paths(
|
|
158
|
+
assignments,
|
|
159
|
+
element.argument,
|
|
160
|
+
rest_expression,
|
|
161
|
+
rest_expression,
|
|
162
|
+
has_default_value
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
/** @type {DestructuredAssignment['expression']} */
|
|
167
|
+
const array_expression = (object) => b.member(expression(object), b.literal(i), true);
|
|
168
|
+
_extract_paths(
|
|
169
|
+
assignments,
|
|
170
|
+
element,
|
|
171
|
+
array_expression,
|
|
172
|
+
array_expression,
|
|
173
|
+
has_default_value
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
break;
|
|
180
|
+
|
|
181
|
+
case 'AssignmentPattern': {
|
|
182
|
+
/** @type {DestructuredAssignment['expression']} */
|
|
183
|
+
const fallback_expression = (object) => build_fallback(expression(object), param.right);
|
|
184
|
+
|
|
185
|
+
if (param.left.type === 'Identifier') {
|
|
186
|
+
assignments.push({
|
|
187
|
+
node: param.left,
|
|
188
|
+
is_rest: false,
|
|
189
|
+
has_default_value: true,
|
|
190
|
+
expression: fallback_expression,
|
|
191
|
+
update_expression
|
|
192
|
+
});
|
|
193
|
+
} else {
|
|
194
|
+
_extract_paths(assignments, param.left, fallback_expression, update_expression, true);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return assignments;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* @param {ESTree.AssignmentOperator} operator
|
|
206
|
+
* @param {ESTree.Identifier | ESTree.MemberExpression} left
|
|
207
|
+
* @param {ESTree.Expression} right
|
|
208
|
+
*/
|
|
209
|
+
export function build_assignment_value(operator, left, right) {
|
|
210
|
+
return operator === '='
|
|
211
|
+
? right
|
|
212
|
+
: // turn something like x += 1 into x = x + 1
|
|
213
|
+
b.binary(/** @type {ESTree.BinaryOperator} */ (operator.slice(0, -1)), left, right);
|
|
214
|
+
}
|