@b9g/crank 0.4.3 → 0.5.0-beta.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/README.md +15 -50
- package/crank.cjs +192 -171
- package/crank.cjs.map +1 -1
- package/crank.d.ts +3 -3
- package/crank.js +192 -172
- package/crank.js.map +1 -1
- package/dom.cjs.map +1 -1
- package/dom.js.map +1 -1
- package/html.cjs.map +1 -1
- package/html.js.map +1 -1
- package/index.cjs +3 -1
- package/index.cjs.map +1 -1
- package/index.d.ts +1 -1
- package/index.js +2 -1
- package/index.js.map +1 -1
- package/package.json +32 -24
- package/umd.js +192 -171
- package/umd.js.map +1 -1
- package/xm.cjs +431 -0
- package/xm.cjs.map +1 -0
- package/xm.d.ts +2 -0
- package/xm.js +428 -0
- package/xm.js.map +1 -0
package/crank.d.ts
CHANGED
|
@@ -166,9 +166,9 @@ export declare function isElement(value: any): value is Element;
|
|
|
166
166
|
* children prop according to any additional arguments passed to the function.
|
|
167
167
|
*/
|
|
168
168
|
export declare function createElement<TTag extends Tag>(tag: TTag, props?: TagProps<TTag> | null | undefined, ...children: Array<unknown>): Element<TTag>;
|
|
169
|
-
/**
|
|
170
|
-
|
|
171
|
-
*/
|
|
169
|
+
/** A single-letter alias for createElement */
|
|
170
|
+
export declare const c: typeof createElement;
|
|
171
|
+
/** Clones a given element, shallowly copying the props object. */
|
|
172
172
|
export declare function cloneElement<TTag extends Tag>(el: Element<TTag>): Element<TTag>;
|
|
173
173
|
/**
|
|
174
174
|
* A helper type which repesents all possible rendered values of an element.
|
package/crank.js
CHANGED
|
@@ -105,6 +105,7 @@ class Element {
|
|
|
105
105
|
this.static_ = static_;
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
|
+
// See Element interface
|
|
108
109
|
Element.prototype.$$typeof = ElementSymbol;
|
|
109
110
|
function isElement(value) {
|
|
110
111
|
return value != null && value.$$typeof === ElementSymbol;
|
|
@@ -127,6 +128,7 @@ function createElement(tag, props, ...children) {
|
|
|
127
128
|
switch (name) {
|
|
128
129
|
case "crank-key":
|
|
129
130
|
case "c-key":
|
|
131
|
+
case "$key":
|
|
130
132
|
// We have to make sure we don’t assign null to the key because we
|
|
131
133
|
// don’t check for null keys in the diffing functions.
|
|
132
134
|
if (props[name] != null) {
|
|
@@ -135,12 +137,14 @@ function createElement(tag, props, ...children) {
|
|
|
135
137
|
break;
|
|
136
138
|
case "crank-ref":
|
|
137
139
|
case "c-ref":
|
|
140
|
+
case "$ref":
|
|
138
141
|
if (typeof props[name] === "function") {
|
|
139
142
|
ref = props[name];
|
|
140
143
|
}
|
|
141
144
|
break;
|
|
142
145
|
case "crank-static":
|
|
143
146
|
case "c-static":
|
|
147
|
+
case "$static":
|
|
144
148
|
static_ = !!props[name];
|
|
145
149
|
break;
|
|
146
150
|
default:
|
|
@@ -154,11 +158,27 @@ function createElement(tag, props, ...children) {
|
|
|
154
158
|
else if (children.length === 1) {
|
|
155
159
|
props1.children = children[0];
|
|
156
160
|
}
|
|
161
|
+
// string aliases for the special tags
|
|
162
|
+
// TODO: Does this logic belong here, or in the Element constructor
|
|
163
|
+
switch (tag) {
|
|
164
|
+
case "$FRAGMENT":
|
|
165
|
+
tag = Fragment;
|
|
166
|
+
break;
|
|
167
|
+
case "$PORTAL":
|
|
168
|
+
tag = Portal;
|
|
169
|
+
break;
|
|
170
|
+
case "$COPY":
|
|
171
|
+
tag = Copy;
|
|
172
|
+
break;
|
|
173
|
+
case "$RAW":
|
|
174
|
+
tag = Raw;
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
157
177
|
return new Element(tag, props1, key, ref, static_);
|
|
158
178
|
}
|
|
159
|
-
/**
|
|
160
|
-
|
|
161
|
-
*/
|
|
179
|
+
/** A single-letter alias for createElement */
|
|
180
|
+
const c = createElement;
|
|
181
|
+
/** Clones a given element, shallowly copying the props object. */
|
|
162
182
|
function cloneElement(el) {
|
|
163
183
|
if (!isElement(el)) {
|
|
164
184
|
throw new TypeError("Cannot clone non-element");
|
|
@@ -732,9 +752,9 @@ const IsDone = 1 << 4;
|
|
|
732
752
|
*
|
|
733
753
|
* NOTE: This is mainly used to prevent some false positives in component
|
|
734
754
|
* yields or returns undefined warnings. The reason we’re using this versus
|
|
735
|
-
* IsUnmounted is a very troubling
|
|
736
|
-
*
|
|
737
|
-
*
|
|
755
|
+
* IsUnmounted is a very troubling test (cascades sync generator parent and
|
|
756
|
+
* sync generator child) where synchronous code causes a stack overflow error
|
|
757
|
+
* in a non-deterministic way. Deeply disturbing stuff.
|
|
738
758
|
*/
|
|
739
759
|
const IsErrored = 1 << 5;
|
|
740
760
|
/**
|
|
@@ -955,13 +975,170 @@ class Context {
|
|
|
955
975
|
provisions.set(key, value);
|
|
956
976
|
}
|
|
957
977
|
addEventListener(type, listener, options) {
|
|
958
|
-
|
|
978
|
+
const impl = this[$ContextImpl];
|
|
979
|
+
let listeners;
|
|
980
|
+
if (!isListenerOrListenerObject(listener)) {
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
983
|
+
else {
|
|
984
|
+
const listeners1 = listenersMap.get(impl);
|
|
985
|
+
if (listeners1) {
|
|
986
|
+
listeners = listeners1;
|
|
987
|
+
}
|
|
988
|
+
else {
|
|
989
|
+
listeners = [];
|
|
990
|
+
listenersMap.set(impl, listeners);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
options = normalizeListenerOptions(options);
|
|
994
|
+
let callback;
|
|
995
|
+
if (typeof listener === "object") {
|
|
996
|
+
callback = () => listener.handleEvent.apply(listener, arguments);
|
|
997
|
+
}
|
|
998
|
+
else {
|
|
999
|
+
callback = listener;
|
|
1000
|
+
}
|
|
1001
|
+
const record = { type, callback, listener, options };
|
|
1002
|
+
if (options.once) {
|
|
1003
|
+
record.callback = function () {
|
|
1004
|
+
const i = listeners.indexOf(record);
|
|
1005
|
+
if (i !== -1) {
|
|
1006
|
+
listeners.splice(i, 1);
|
|
1007
|
+
}
|
|
1008
|
+
return callback.apply(this, arguments);
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
if (listeners.some((record1) => record.type === record1.type &&
|
|
1012
|
+
record.listener === record1.listener &&
|
|
1013
|
+
!record.options.capture === !record1.options.capture)) {
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
1016
|
+
listeners.push(record);
|
|
1017
|
+
// TODO: is it possible to separate out the EventTarget delegation logic
|
|
1018
|
+
for (const value of getChildValues(impl.ret)) {
|
|
1019
|
+
if (isEventTarget(value)) {
|
|
1020
|
+
value.addEventListener(record.type, record.callback, record.options);
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
959
1023
|
}
|
|
960
1024
|
removeEventListener(type, listener, options) {
|
|
961
|
-
|
|
1025
|
+
const impl = this[$ContextImpl];
|
|
1026
|
+
const listeners = listenersMap.get(impl);
|
|
1027
|
+
if (listeners == null || !isListenerOrListenerObject(listener)) {
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
1030
|
+
const options1 = normalizeListenerOptions(options);
|
|
1031
|
+
const i = listeners.findIndex((record) => record.type === type &&
|
|
1032
|
+
record.listener === listener &&
|
|
1033
|
+
!record.options.capture === !options1.capture);
|
|
1034
|
+
if (i === -1) {
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1037
|
+
const record = listeners[i];
|
|
1038
|
+
listeners.splice(i, 1);
|
|
1039
|
+
// TODO: is it possible to separate out the EventTarget delegation logic
|
|
1040
|
+
for (const value of getChildValues(impl.ret)) {
|
|
1041
|
+
if (isEventTarget(value)) {
|
|
1042
|
+
value.removeEventListener(record.type, record.callback, record.options);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
962
1045
|
}
|
|
963
1046
|
dispatchEvent(ev) {
|
|
964
|
-
|
|
1047
|
+
const impl = this[$ContextImpl];
|
|
1048
|
+
const path = [];
|
|
1049
|
+
for (let parent = impl.parent; parent !== undefined; parent = parent.parent) {
|
|
1050
|
+
path.push(parent);
|
|
1051
|
+
}
|
|
1052
|
+
// We patch the stopImmediatePropagation method because ev.cancelBubble
|
|
1053
|
+
// only informs us if stopPropagation was called and there are no
|
|
1054
|
+
// properties which inform us if stopImmediatePropagation was called.
|
|
1055
|
+
let immediateCancelBubble = false;
|
|
1056
|
+
const stopImmediatePropagation = ev.stopImmediatePropagation;
|
|
1057
|
+
setEventProperty(ev, "stopImmediatePropagation", () => {
|
|
1058
|
+
immediateCancelBubble = true;
|
|
1059
|
+
return stopImmediatePropagation.call(ev);
|
|
1060
|
+
});
|
|
1061
|
+
setEventProperty(ev, "target", impl.ctx);
|
|
1062
|
+
// The only possible errors in this block are errors thrown by callbacks,
|
|
1063
|
+
// and dispatchEvent will only log these errors rather than throwing
|
|
1064
|
+
// them. Therefore, we place all code in a try block, log errors in the
|
|
1065
|
+
// catch block, and use an unsafe return statement in the finally block.
|
|
1066
|
+
//
|
|
1067
|
+
// Each early return within the try block returns true because while the
|
|
1068
|
+
// return value is overridden in the finally block, TypeScript
|
|
1069
|
+
// (justifiably) does not recognize the unsafe return statement.
|
|
1070
|
+
//
|
|
1071
|
+
// TODO: Run all callbacks even if one of them errors
|
|
1072
|
+
try {
|
|
1073
|
+
setEventProperty(ev, "eventPhase", CAPTURING_PHASE);
|
|
1074
|
+
for (let i = path.length - 1; i >= 0; i--) {
|
|
1075
|
+
const target = path[i];
|
|
1076
|
+
const listeners = listenersMap.get(target);
|
|
1077
|
+
if (listeners) {
|
|
1078
|
+
setEventProperty(ev, "currentTarget", target.ctx);
|
|
1079
|
+
for (const record of listeners) {
|
|
1080
|
+
if (record.type === ev.type && record.options.capture) {
|
|
1081
|
+
record.callback.call(target.ctx, ev);
|
|
1082
|
+
if (immediateCancelBubble) {
|
|
1083
|
+
return true;
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
if (ev.cancelBubble) {
|
|
1089
|
+
return true;
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
{
|
|
1093
|
+
const listeners = listenersMap.get(impl);
|
|
1094
|
+
if (listeners) {
|
|
1095
|
+
setEventProperty(ev, "eventPhase", AT_TARGET);
|
|
1096
|
+
setEventProperty(ev, "currentTarget", impl.ctx);
|
|
1097
|
+
for (const record of listeners) {
|
|
1098
|
+
if (record.type === ev.type) {
|
|
1099
|
+
record.callback.call(impl.ctx, ev);
|
|
1100
|
+
if (immediateCancelBubble) {
|
|
1101
|
+
return true;
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
if (ev.cancelBubble) {
|
|
1106
|
+
return true;
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
if (ev.bubbles) {
|
|
1111
|
+
setEventProperty(ev, "eventPhase", BUBBLING_PHASE);
|
|
1112
|
+
for (let i = 0; i < path.length; i++) {
|
|
1113
|
+
const target = path[i];
|
|
1114
|
+
const listeners = listenersMap.get(target);
|
|
1115
|
+
if (listeners) {
|
|
1116
|
+
setEventProperty(ev, "currentTarget", target.ctx);
|
|
1117
|
+
for (const record of listeners) {
|
|
1118
|
+
if (record.type === ev.type && !record.options.capture) {
|
|
1119
|
+
record.callback.call(target.ctx, ev);
|
|
1120
|
+
if (immediateCancelBubble) {
|
|
1121
|
+
return true;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
if (ev.cancelBubble) {
|
|
1127
|
+
return true;
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
catch (err) {
|
|
1133
|
+
// TODO: Use setTimeout to rethrow the error.
|
|
1134
|
+
console.error(err);
|
|
1135
|
+
}
|
|
1136
|
+
finally {
|
|
1137
|
+
setEventProperty(ev, "eventPhase", NONE);
|
|
1138
|
+
setEventProperty(ev, "currentTarget", null);
|
|
1139
|
+
// eslint-disable-next-line no-unsafe-finally
|
|
1140
|
+
return !ev.defaultPrevented;
|
|
1141
|
+
}
|
|
965
1142
|
}
|
|
966
1143
|
}
|
|
967
1144
|
/*** PRIVATE CONTEXT FUNCTIONS ***/
|
|
@@ -1362,168 +1539,11 @@ const CAPTURING_PHASE = 1;
|
|
|
1362
1539
|
const AT_TARGET = 2;
|
|
1363
1540
|
const BUBBLING_PHASE = 3;
|
|
1364
1541
|
const listenersMap = new WeakMap();
|
|
1365
|
-
function
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
else {
|
|
1371
|
-
const listeners1 = listenersMap.get(ctx);
|
|
1372
|
-
if (listeners1) {
|
|
1373
|
-
listeners = listeners1;
|
|
1374
|
-
}
|
|
1375
|
-
else {
|
|
1376
|
-
listeners = [];
|
|
1377
|
-
listenersMap.set(ctx, listeners);
|
|
1378
|
-
}
|
|
1379
|
-
}
|
|
1380
|
-
options = normalizeListenerOptions(options);
|
|
1381
|
-
let callback;
|
|
1382
|
-
if (typeof listener === "object") {
|
|
1383
|
-
callback = () => listener.handleEvent.apply(listener, arguments);
|
|
1384
|
-
}
|
|
1385
|
-
else {
|
|
1386
|
-
callback = listener;
|
|
1387
|
-
}
|
|
1388
|
-
const record = { type, callback, listener, options };
|
|
1389
|
-
if (options.once) {
|
|
1390
|
-
record.callback = function () {
|
|
1391
|
-
const i = listeners.indexOf(record);
|
|
1392
|
-
if (i !== -1) {
|
|
1393
|
-
listeners.splice(i, 1);
|
|
1394
|
-
}
|
|
1395
|
-
return callback.apply(this, arguments);
|
|
1396
|
-
};
|
|
1397
|
-
}
|
|
1398
|
-
if (listeners.some((record1) => record.type === record1.type &&
|
|
1399
|
-
record.listener === record1.listener &&
|
|
1400
|
-
!record.options.capture === !record1.options.capture)) {
|
|
1401
|
-
return;
|
|
1402
|
-
}
|
|
1403
|
-
listeners.push(record);
|
|
1404
|
-
// TODO: is it possible to separate out the EventTarget delegation logic
|
|
1405
|
-
for (const value of getChildValues(ctx.ret)) {
|
|
1406
|
-
if (isEventTarget(value)) {
|
|
1407
|
-
value.addEventListener(record.type, record.callback, record.options);
|
|
1408
|
-
}
|
|
1409
|
-
}
|
|
1410
|
-
}
|
|
1411
|
-
function removeEventListener(ctx, type, listener, options) {
|
|
1412
|
-
const listeners = listenersMap.get(ctx);
|
|
1413
|
-
if (listener == null || listeners == null) {
|
|
1414
|
-
return;
|
|
1415
|
-
}
|
|
1416
|
-
const options1 = normalizeListenerOptions(options);
|
|
1417
|
-
const i = listeners.findIndex((record) => record.type === type &&
|
|
1418
|
-
record.listener === listener &&
|
|
1419
|
-
!record.options.capture === !options1.capture);
|
|
1420
|
-
if (i === -1) {
|
|
1421
|
-
return;
|
|
1422
|
-
}
|
|
1423
|
-
const record = listeners[i];
|
|
1424
|
-
listeners.splice(i, 1);
|
|
1425
|
-
// TODO: is it possible to separate out the EventTarget delegation logic
|
|
1426
|
-
for (const value of getChildValues(ctx.ret)) {
|
|
1427
|
-
if (isEventTarget(value)) {
|
|
1428
|
-
value.removeEventListener(record.type, record.callback, record.options);
|
|
1429
|
-
}
|
|
1430
|
-
}
|
|
1431
|
-
}
|
|
1432
|
-
function dispatchEvent(ctx, ev) {
|
|
1433
|
-
const path = [];
|
|
1434
|
-
for (let parent = ctx.parent; parent !== undefined; parent = parent.parent) {
|
|
1435
|
-
path.push(parent);
|
|
1436
|
-
}
|
|
1437
|
-
// We patch the stopImmediatePropagation method because ev.cancelBubble
|
|
1438
|
-
// only informs us if stopPropagation was called and there are no
|
|
1439
|
-
// properties which inform us if stopImmediatePropagation was called.
|
|
1440
|
-
let immediateCancelBubble = false;
|
|
1441
|
-
const stopImmediatePropagation = ev.stopImmediatePropagation;
|
|
1442
|
-
setEventProperty(ev, "stopImmediatePropagation", () => {
|
|
1443
|
-
immediateCancelBubble = true;
|
|
1444
|
-
return stopImmediatePropagation.call(ev);
|
|
1445
|
-
});
|
|
1446
|
-
setEventProperty(ev, "target", ctx.ctx);
|
|
1447
|
-
// The only possible errors in this block are errors thrown by callbacks,
|
|
1448
|
-
// and dispatchEvent will only log these errors rather than throwing
|
|
1449
|
-
// them. Therefore, we place all code in a try block, log errors in the
|
|
1450
|
-
// catch block, and use an unsafe return statement in the finally block.
|
|
1451
|
-
//
|
|
1452
|
-
// Each early return within the try block returns true because while the
|
|
1453
|
-
// return value is overridden in the finally block, TypeScript
|
|
1454
|
-
// (justifiably) does not recognize the unsafe return statement.
|
|
1455
|
-
//
|
|
1456
|
-
// TODO: Run all callbacks even if one of them errors
|
|
1457
|
-
try {
|
|
1458
|
-
setEventProperty(ev, "eventPhase", CAPTURING_PHASE);
|
|
1459
|
-
for (let i = path.length - 1; i >= 0; i--) {
|
|
1460
|
-
const target = path[i];
|
|
1461
|
-
const listeners = listenersMap.get(target);
|
|
1462
|
-
if (listeners) {
|
|
1463
|
-
setEventProperty(ev, "currentTarget", target.ctx);
|
|
1464
|
-
for (const record of listeners) {
|
|
1465
|
-
if (record.type === ev.type && record.options.capture) {
|
|
1466
|
-
record.callback.call(target.ctx, ev);
|
|
1467
|
-
if (immediateCancelBubble) {
|
|
1468
|
-
return true;
|
|
1469
|
-
}
|
|
1470
|
-
}
|
|
1471
|
-
}
|
|
1472
|
-
}
|
|
1473
|
-
if (ev.cancelBubble) {
|
|
1474
|
-
return true;
|
|
1475
|
-
}
|
|
1476
|
-
}
|
|
1477
|
-
{
|
|
1478
|
-
const listeners = listenersMap.get(ctx);
|
|
1479
|
-
if (listeners) {
|
|
1480
|
-
setEventProperty(ev, "eventPhase", AT_TARGET);
|
|
1481
|
-
setEventProperty(ev, "currentTarget", ctx.ctx);
|
|
1482
|
-
for (const record of listeners) {
|
|
1483
|
-
if (record.type === ev.type) {
|
|
1484
|
-
record.callback.call(ctx.ctx, ev);
|
|
1485
|
-
if (immediateCancelBubble) {
|
|
1486
|
-
return true;
|
|
1487
|
-
}
|
|
1488
|
-
}
|
|
1489
|
-
}
|
|
1490
|
-
if (ev.cancelBubble) {
|
|
1491
|
-
return true;
|
|
1492
|
-
}
|
|
1493
|
-
}
|
|
1494
|
-
}
|
|
1495
|
-
if (ev.bubbles) {
|
|
1496
|
-
setEventProperty(ev, "eventPhase", BUBBLING_PHASE);
|
|
1497
|
-
for (let i = 0; i < path.length; i++) {
|
|
1498
|
-
const target = path[i];
|
|
1499
|
-
const listeners = listenersMap.get(target);
|
|
1500
|
-
if (listeners) {
|
|
1501
|
-
setEventProperty(ev, "currentTarget", target.ctx);
|
|
1502
|
-
for (const record of listeners) {
|
|
1503
|
-
if (record.type === ev.type && !record.options.capture) {
|
|
1504
|
-
record.callback.call(target.ctx, ev);
|
|
1505
|
-
if (immediateCancelBubble) {
|
|
1506
|
-
return true;
|
|
1507
|
-
}
|
|
1508
|
-
}
|
|
1509
|
-
}
|
|
1510
|
-
}
|
|
1511
|
-
if (ev.cancelBubble) {
|
|
1512
|
-
return true;
|
|
1513
|
-
}
|
|
1514
|
-
}
|
|
1515
|
-
}
|
|
1516
|
-
}
|
|
1517
|
-
catch (err) {
|
|
1518
|
-
// TODO: Use setTimeout to rethrow the error.
|
|
1519
|
-
console.error(err);
|
|
1520
|
-
}
|
|
1521
|
-
finally {
|
|
1522
|
-
setEventProperty(ev, "eventPhase", NONE);
|
|
1523
|
-
setEventProperty(ev, "currentTarget", null);
|
|
1524
|
-
// eslint-disable-next-line no-unsafe-finally
|
|
1525
|
-
return !ev.defaultPrevented;
|
|
1526
|
-
}
|
|
1542
|
+
function isListenerOrListenerObject(value) {
|
|
1543
|
+
return (typeof value === "function" ||
|
|
1544
|
+
(value !== null &&
|
|
1545
|
+
typeof value === "object" &&
|
|
1546
|
+
typeof value.handleEvent === "function"));
|
|
1527
1547
|
}
|
|
1528
1548
|
function normalizeListenerOptions(options) {
|
|
1529
1549
|
if (typeof options === "boolean") {
|
|
@@ -1635,5 +1655,5 @@ function propagateError(ctx, err) {
|
|
|
1635
1655
|
// default export. Prefer named exports when importing directly.
|
|
1636
1656
|
var crank = { createElement, Fragment };
|
|
1637
1657
|
|
|
1638
|
-
export { Context, Copy, Element, Fragment, Portal, Raw, Renderer, cloneElement, createElement, crank as default, isElement };
|
|
1658
|
+
export { Context, Copy, Element, Fragment, Portal, Raw, Renderer, c, cloneElement, createElement, crank as default, isElement };
|
|
1639
1659
|
//# sourceMappingURL=crank.js.map
|