@sigx/lynx-runtime-main 0.4.3 → 0.4.5
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/dist/list-mt.d.ts +65 -0
- package/dist/list-mt.js +236 -0
- package/dist/ops-apply.js +27 -0
- package/package.json +2 -2
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main Thread native `<list>` recycler support.
|
|
3
|
+
*
|
|
4
|
+
* Lynx's `<list>` is NOT a plain scrolling container — it's a managed recycler.
|
|
5
|
+
* Native pulls each visible cell by calling `componentAtIndex(cellIndex)` and
|
|
6
|
+
* recycles offscreen cells via `enqueueComponent(sign)`. If its
|
|
7
|
+
* `update-list-info` metadata is never set, native crashes during layout
|
|
8
|
+
* (`UIList.onLayoutCompleted` NPE — issue #120).
|
|
9
|
+
*
|
|
10
|
+
* The reference framework (`@lynx-js/react`) renders each `<list-item>` subtree
|
|
11
|
+
* on demand inside `componentAtIndex`. The sigx renderer is different: the
|
|
12
|
+
* Background Thread eagerly creates ALL `<list-item>` elements (and their
|
|
13
|
+
* subtrees) on the Main Thread, just like any other children. So here
|
|
14
|
+
* `componentAtIndex` does not render anything — it simply returns the sign of
|
|
15
|
+
* the already-built element for that index, appending it to the list on first
|
|
16
|
+
* pull so native can find it via its unique id.
|
|
17
|
+
*
|
|
18
|
+
* What this module owns:
|
|
19
|
+
* - Creating `<list>` via `__CreateList` (so the callbacks are registered).
|
|
20
|
+
* - Tracking each list's ordered `<list-item>` children (BG insertion order)
|
|
21
|
+
* and their per-item platform info (item-key etc.).
|
|
22
|
+
* - Emitting `update-list-info` diffs (insert/remove actions) at the end of
|
|
23
|
+
* each ops batch so native knows how many cells exist and their keys.
|
|
24
|
+
*
|
|
25
|
+
* `<list-item>` children are intercepted here instead of being appended to the
|
|
26
|
+
* list element directly (the recycler owns attachment via `componentAtIndex`).
|
|
27
|
+
*/
|
|
28
|
+
/** True when `internalId` is a `<list>` element managed by this module. */
|
|
29
|
+
export declare function isListElement(internalId: number): boolean;
|
|
30
|
+
/** True when `internalId` is a direct `<list-item>` child of some `<list>`. */
|
|
31
|
+
export declare function isListChild(internalId: number): boolean;
|
|
32
|
+
/** Create a `<list>` element and register its recycler callbacks. */
|
|
33
|
+
export declare function createListElement(internalId: number): MainThreadElement;
|
|
34
|
+
/**
|
|
35
|
+
* Record a `<list-item>` inserted into a `<list>`. We do NOT append it to the
|
|
36
|
+
* list element here — the recycler attaches it on demand via
|
|
37
|
+
* `componentAtIndex`. `anchorInternalId` is the real sibling to insert before,
|
|
38
|
+
* or -1 to append.
|
|
39
|
+
*/
|
|
40
|
+
export declare function listInsertChild(listInternalId: number, childInternalId: number, anchorInternalId: number): void;
|
|
41
|
+
/** Record a `<list-item>` removed from a `<list>` and detach its element. */
|
|
42
|
+
export declare function listRemoveChild(listInternalId: number, childInternalId: number): void;
|
|
43
|
+
/** Tear down a `<list>` element (detach callbacks, drop all state). */
|
|
44
|
+
export declare function destroyListElement(internalId: number): void;
|
|
45
|
+
/**
|
|
46
|
+
* Record a platform-info prop on a `<list-item>`. Returns true if `key` is a
|
|
47
|
+
* recognised platform-info key (the caller still sets it as a normal element
|
|
48
|
+
* attribute regardless). Safe to call before the item's insert op arrives —
|
|
49
|
+
* the info is stashed by child id and read at flush time.
|
|
50
|
+
*/
|
|
51
|
+
export declare function noteListItemProp(childInternalId: number, key: string, value: unknown): void;
|
|
52
|
+
/**
|
|
53
|
+
* Emit `update-list-info` diffs for every list whose children changed during
|
|
54
|
+
* the current ops batch. Called once per batch, before the final
|
|
55
|
+
* `__FlushElementTree`.
|
|
56
|
+
*
|
|
57
|
+
* The diff is intentionally minimal — insert/remove only (no move/update). It
|
|
58
|
+
* covers the common cases (initial render, append, delete). `removeAction`
|
|
59
|
+
* carries ascending OLD indices; `insertAction` carries ascending NEW
|
|
60
|
+
* positions, each with the item's type and platform info. This matches the
|
|
61
|
+
* order the host/native recycler applies them (remove first, then insert).
|
|
62
|
+
*/
|
|
63
|
+
export declare function flushDirtyLists(): void;
|
|
64
|
+
/** Reset all list state — for testing and hot reload. */
|
|
65
|
+
export declare function resetListState(): void;
|
package/dist/list-mt.js
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main Thread native `<list>` recycler support.
|
|
3
|
+
*
|
|
4
|
+
* Lynx's `<list>` is NOT a plain scrolling container — it's a managed recycler.
|
|
5
|
+
* Native pulls each visible cell by calling `componentAtIndex(cellIndex)` and
|
|
6
|
+
* recycles offscreen cells via `enqueueComponent(sign)`. If its
|
|
7
|
+
* `update-list-info` metadata is never set, native crashes during layout
|
|
8
|
+
* (`UIList.onLayoutCompleted` NPE — issue #120).
|
|
9
|
+
*
|
|
10
|
+
* The reference framework (`@lynx-js/react`) renders each `<list-item>` subtree
|
|
11
|
+
* on demand inside `componentAtIndex`. The sigx renderer is different: the
|
|
12
|
+
* Background Thread eagerly creates ALL `<list-item>` elements (and their
|
|
13
|
+
* subtrees) on the Main Thread, just like any other children. So here
|
|
14
|
+
* `componentAtIndex` does not render anything — it simply returns the sign of
|
|
15
|
+
* the already-built element for that index, appending it to the list on first
|
|
16
|
+
* pull so native can find it via its unique id.
|
|
17
|
+
*
|
|
18
|
+
* What this module owns:
|
|
19
|
+
* - Creating `<list>` via `__CreateList` (so the callbacks are registered).
|
|
20
|
+
* - Tracking each list's ordered `<list-item>` children (BG insertion order)
|
|
21
|
+
* and their per-item platform info (item-key etc.).
|
|
22
|
+
* - Emitting `update-list-info` diffs (insert/remove actions) at the end of
|
|
23
|
+
* each ops batch so native knows how many cells exist and their keys.
|
|
24
|
+
*
|
|
25
|
+
* `<list-item>` children are intercepted here instead of being appended to the
|
|
26
|
+
* list element directly (the recycler owns attachment via `componentAtIndex`).
|
|
27
|
+
*/
|
|
28
|
+
import { elements, pageUniqueId } from './element-registry.js';
|
|
29
|
+
/**
|
|
30
|
+
* Per-`<list-item>` platform-info attribute keys (kebab-case). These are
|
|
31
|
+
* forwarded to native both as element attributes (via the normal SET_PROP →
|
|
32
|
+
* __SetAttribute path) and inside `update-list-info`'s insertAction entries.
|
|
33
|
+
*/
|
|
34
|
+
const PLATFORM_INFO_KEYS = new Set([
|
|
35
|
+
'item-key',
|
|
36
|
+
'full-span',
|
|
37
|
+
'sticky-top',
|
|
38
|
+
'sticky-bottom',
|
|
39
|
+
'estimated-height',
|
|
40
|
+
'estimated-height-px',
|
|
41
|
+
'estimated-main-axis-size-px',
|
|
42
|
+
'reuse-identifier',
|
|
43
|
+
'recyclable',
|
|
44
|
+
]);
|
|
45
|
+
const listsByInternalId = new Map();
|
|
46
|
+
const listByListID = new Map();
|
|
47
|
+
/** child internal id → owning list internal id */
|
|
48
|
+
const listItemOwner = new Map();
|
|
49
|
+
/** child internal id → per-item platform info ({ 'item-key': … }) */
|
|
50
|
+
const itemPlatformInfo = new Map();
|
|
51
|
+
/** True when `internalId` is a `<list>` element managed by this module. */
|
|
52
|
+
export function isListElement(internalId) {
|
|
53
|
+
return listsByInternalId.has(internalId);
|
|
54
|
+
}
|
|
55
|
+
/** True when `internalId` is a direct `<list-item>` child of some `<list>`. */
|
|
56
|
+
export function isListChild(internalId) {
|
|
57
|
+
return listItemOwner.has(internalId);
|
|
58
|
+
}
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Recycler callbacks (invoked by native during layout, on the Main Thread)
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
function componentAtIndex(_list, listID, cellIndex, operationID, _enableReuseNotification) {
|
|
63
|
+
const state = listByListID.get(listID);
|
|
64
|
+
if (!state)
|
|
65
|
+
return -1;
|
|
66
|
+
const childInternalId = state.order[cellIndex];
|
|
67
|
+
if (childInternalId === undefined)
|
|
68
|
+
return -1;
|
|
69
|
+
const root = elements.get(childInternalId);
|
|
70
|
+
if (!root)
|
|
71
|
+
return -1;
|
|
72
|
+
const sign = __GetElementUniqueID(root);
|
|
73
|
+
// The element already exists (BG built it eagerly). Append on first pull so
|
|
74
|
+
// native can resolve it by sign; the guard prevents a double-append when the
|
|
75
|
+
// cell scrolls back into view.
|
|
76
|
+
if (!state.appended.has(childInternalId)) {
|
|
77
|
+
__AppendElement(state.listEl, root);
|
|
78
|
+
state.appended.add(childInternalId);
|
|
79
|
+
}
|
|
80
|
+
__FlushElementTree(root, {
|
|
81
|
+
triggerLayout: true,
|
|
82
|
+
operationID,
|
|
83
|
+
elementID: sign,
|
|
84
|
+
listID,
|
|
85
|
+
});
|
|
86
|
+
return sign;
|
|
87
|
+
}
|
|
88
|
+
function enqueueComponent(_list, _listID, _sign) {
|
|
89
|
+
// No-op. Each `<list-item>` has its own dedicated, already-rendered element,
|
|
90
|
+
// so we never recycle one element's subtree to display a different item.
|
|
91
|
+
// Native detaches the offscreen view on its own; the element stays in the
|
|
92
|
+
// tree so `componentAtIndex` can re-surface it on scroll-back.
|
|
93
|
+
}
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
// Lifecycle, invoked from ops-apply.ts
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
/** Create a `<list>` element and register its recycler callbacks. */
|
|
98
|
+
export function createListElement(internalId) {
|
|
99
|
+
const listEl = __CreateList(pageUniqueId, componentAtIndex, enqueueComponent);
|
|
100
|
+
const listID = __GetElementUniqueID(listEl);
|
|
101
|
+
const state = {
|
|
102
|
+
internalId,
|
|
103
|
+
listEl,
|
|
104
|
+
listID,
|
|
105
|
+
order: [],
|
|
106
|
+
committed: [],
|
|
107
|
+
appended: new Set(),
|
|
108
|
+
dirty: false,
|
|
109
|
+
};
|
|
110
|
+
listsByInternalId.set(internalId, state);
|
|
111
|
+
listByListID.set(listID, state);
|
|
112
|
+
return listEl;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Record a `<list-item>` inserted into a `<list>`. We do NOT append it to the
|
|
116
|
+
* list element here — the recycler attaches it on demand via
|
|
117
|
+
* `componentAtIndex`. `anchorInternalId` is the real sibling to insert before,
|
|
118
|
+
* or -1 to append.
|
|
119
|
+
*/
|
|
120
|
+
export function listInsertChild(listInternalId, childInternalId, anchorInternalId) {
|
|
121
|
+
const state = listsByInternalId.get(listInternalId);
|
|
122
|
+
if (!state)
|
|
123
|
+
return;
|
|
124
|
+
const idx = anchorInternalId === -1 ? -1 : state.order.indexOf(anchorInternalId);
|
|
125
|
+
if (idx === -1)
|
|
126
|
+
state.order.push(childInternalId);
|
|
127
|
+
else
|
|
128
|
+
state.order.splice(idx, 0, childInternalId);
|
|
129
|
+
listItemOwner.set(childInternalId, listInternalId);
|
|
130
|
+
state.dirty = true;
|
|
131
|
+
}
|
|
132
|
+
/** Record a `<list-item>` removed from a `<list>` and detach its element. */
|
|
133
|
+
export function listRemoveChild(listInternalId, childInternalId) {
|
|
134
|
+
const state = listsByInternalId.get(listInternalId);
|
|
135
|
+
if (!state)
|
|
136
|
+
return;
|
|
137
|
+
const idx = state.order.indexOf(childInternalId);
|
|
138
|
+
if (idx !== -1)
|
|
139
|
+
state.order.splice(idx, 1);
|
|
140
|
+
if (state.appended.delete(childInternalId)) {
|
|
141
|
+
const child = elements.get(childInternalId);
|
|
142
|
+
if (child)
|
|
143
|
+
__RemoveElement(state.listEl, child);
|
|
144
|
+
}
|
|
145
|
+
listItemOwner.delete(childInternalId);
|
|
146
|
+
itemPlatformInfo.delete(childInternalId);
|
|
147
|
+
state.dirty = true;
|
|
148
|
+
}
|
|
149
|
+
/** Tear down a `<list>` element (detach callbacks, drop all state). */
|
|
150
|
+
export function destroyListElement(internalId) {
|
|
151
|
+
const state = listsByInternalId.get(internalId);
|
|
152
|
+
if (!state)
|
|
153
|
+
return;
|
|
154
|
+
__UpdateListCallbacks(state.listEl, null, null);
|
|
155
|
+
listByListID.delete(state.listID);
|
|
156
|
+
for (const childId of state.order) {
|
|
157
|
+
listItemOwner.delete(childId);
|
|
158
|
+
itemPlatformInfo.delete(childId);
|
|
159
|
+
}
|
|
160
|
+
listsByInternalId.delete(internalId);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Record a platform-info prop on a `<list-item>`. Returns true if `key` is a
|
|
164
|
+
* recognised platform-info key (the caller still sets it as a normal element
|
|
165
|
+
* attribute regardless). Safe to call before the item's insert op arrives —
|
|
166
|
+
* the info is stashed by child id and read at flush time.
|
|
167
|
+
*/
|
|
168
|
+
export function noteListItemProp(childInternalId, key, value) {
|
|
169
|
+
if (!PLATFORM_INFO_KEYS.has(key))
|
|
170
|
+
return;
|
|
171
|
+
let info = itemPlatformInfo.get(childInternalId);
|
|
172
|
+
if (!info) {
|
|
173
|
+
info = {};
|
|
174
|
+
itemPlatformInfo.set(childInternalId, info);
|
|
175
|
+
}
|
|
176
|
+
info[key] = value;
|
|
177
|
+
const owner = listItemOwner.get(childInternalId);
|
|
178
|
+
if (owner !== undefined) {
|
|
179
|
+
const st = listsByInternalId.get(owner);
|
|
180
|
+
if (st)
|
|
181
|
+
st.dirty = true;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Emit `update-list-info` diffs for every list whose children changed during
|
|
186
|
+
* the current ops batch. Called once per batch, before the final
|
|
187
|
+
* `__FlushElementTree`.
|
|
188
|
+
*
|
|
189
|
+
* The diff is intentionally minimal — insert/remove only (no move/update). It
|
|
190
|
+
* covers the common cases (initial render, append, delete). `removeAction`
|
|
191
|
+
* carries ascending OLD indices; `insertAction` carries ascending NEW
|
|
192
|
+
* positions, each with the item's type and platform info. This matches the
|
|
193
|
+
* order the host/native recycler applies them (remove first, then insert).
|
|
194
|
+
*/
|
|
195
|
+
export function flushDirtyLists() {
|
|
196
|
+
for (const state of listsByInternalId.values()) {
|
|
197
|
+
if (!state.dirty)
|
|
198
|
+
continue;
|
|
199
|
+
state.dirty = false;
|
|
200
|
+
const oldArr = state.committed;
|
|
201
|
+
const newArr = state.order;
|
|
202
|
+
const oldSet = new Set(oldArr);
|
|
203
|
+
const newSet = new Set(newArr);
|
|
204
|
+
const removeAction = [];
|
|
205
|
+
for (let i = 0; i < oldArr.length; i++) {
|
|
206
|
+
if (!newSet.has(oldArr[i]))
|
|
207
|
+
removeAction.push(i);
|
|
208
|
+
}
|
|
209
|
+
const insertAction = [];
|
|
210
|
+
for (let pos = 0; pos < newArr.length; pos++) {
|
|
211
|
+
const childInternalId = newArr[pos];
|
|
212
|
+
if (!oldSet.has(childInternalId)) {
|
|
213
|
+
const info = itemPlatformInfo.get(childInternalId) ?? {};
|
|
214
|
+
insertAction.push({ position: pos, type: 'list-item', ...info });
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
state.committed = newArr.slice();
|
|
218
|
+
if (removeAction.length === 0 && insertAction.length === 0)
|
|
219
|
+
continue;
|
|
220
|
+
__SetAttribute(state.listEl, 'update-list-info', {
|
|
221
|
+
insertAction,
|
|
222
|
+
removeAction,
|
|
223
|
+
updateAction: [],
|
|
224
|
+
});
|
|
225
|
+
// Re-affirm the callbacks after every diff (mirrors the reference runtime).
|
|
226
|
+
// Our closures read live state, so this is a defensive no-op rebind.
|
|
227
|
+
__UpdateListCallbacks(state.listEl, componentAtIndex, enqueueComponent);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/** Reset all list state — for testing and hot reload. */
|
|
231
|
+
export function resetListState() {
|
|
232
|
+
listsByInternalId.clear();
|
|
233
|
+
listByListID.clear();
|
|
234
|
+
listItemOwner.clear();
|
|
235
|
+
itemPlatformInfo.clear();
|
|
236
|
+
}
|
package/dist/ops-apply.js
CHANGED
|
@@ -11,6 +11,7 @@ import { elements, pageUniqueId, setPageUniqueId, } from './element-registry.js'
|
|
|
11
11
|
import { resetWorkletEvents } from './worklet-events.js';
|
|
12
12
|
import { setSlotBgSign, setSlotWorklet, flushDirtySlots, resetSlotStates, } from './event-slots.js';
|
|
13
13
|
import { flushAvBridgePublishes, flushAnimatedStyleBindings, registerAnimatedStyleBinding, unregisterAnimatedStyleBinding, resetAnimatedStyleBindings, } from './animated-bridge-mt.js';
|
|
14
|
+
import { createListElement, destroyListElement, flushDirtyLists, isListElement, listInsertChild, listRemoveChild, noteListItemProp, resetListState, } from './list-mt.js';
|
|
14
15
|
/**
|
|
15
16
|
* Placeholder element inserted by renderPage() to give the host a non-empty
|
|
16
17
|
* tree immediately, suppressing the "loadCard failed USER_RUNTIME_ERROR"
|
|
@@ -127,6 +128,12 @@ export function applyOps(ops) {
|
|
|
127
128
|
if (type === '__comment') {
|
|
128
129
|
el = __CreateRawText('');
|
|
129
130
|
}
|
|
131
|
+
else if (type === 'list') {
|
|
132
|
+
// `<list>` is created via __CreateList so its recycler callbacks are
|
|
133
|
+
// registered up front (issue #120). list-mt.ts owns its state.
|
|
134
|
+
el = createListElement(id);
|
|
135
|
+
__SetCSSId([el], 0);
|
|
136
|
+
}
|
|
130
137
|
else {
|
|
131
138
|
el = createTypedElement(type, pageUniqueId);
|
|
132
139
|
__SetCSSId([el], 0);
|
|
@@ -149,6 +156,12 @@ export function applyOps(ops) {
|
|
|
149
156
|
const parentId = ops[i++];
|
|
150
157
|
const childId = ops[i++];
|
|
151
158
|
const anchorId = ops[i++];
|
|
159
|
+
// `<list>` children are owned by the recycler — record order instead of
|
|
160
|
+
// appending; native attaches them on demand via componentAtIndex.
|
|
161
|
+
if (isListElement(parentId)) {
|
|
162
|
+
listInsertChild(parentId, childId, anchorId);
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
152
165
|
const parent = elements.get(parentId);
|
|
153
166
|
const child = elements.get(childId);
|
|
154
167
|
if (parent && child) {
|
|
@@ -166,6 +179,13 @@ export function applyOps(ops) {
|
|
|
166
179
|
case OP.REMOVE: {
|
|
167
180
|
const _parentId = ops[i++];
|
|
168
181
|
const childId = ops[i++];
|
|
182
|
+
if (isListElement(_parentId)) {
|
|
183
|
+
listRemoveChild(_parentId, childId);
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
// Tearing down a `<list>` itself — detach its recycler callbacks first.
|
|
187
|
+
if (isListElement(childId))
|
|
188
|
+
destroyListElement(childId);
|
|
169
189
|
const parent = elements.get(_parentId);
|
|
170
190
|
const child = elements.get(childId);
|
|
171
191
|
if (parent && child) {
|
|
@@ -180,6 +200,9 @@ export function applyOps(ops) {
|
|
|
180
200
|
const el = elements.get(id);
|
|
181
201
|
if (el)
|
|
182
202
|
__SetAttribute(el, key, value);
|
|
203
|
+
// Mirror `<list-item>` platform-info props (item-key, full-span, …)
|
|
204
|
+
// into the list's update-list-info metadata (no-op for other keys).
|
|
205
|
+
noteListItemProp(id, key, value);
|
|
183
206
|
break;
|
|
184
207
|
}
|
|
185
208
|
case OP.SET_TEXT: {
|
|
@@ -424,6 +447,9 @@ export function applyOps(ops) {
|
|
|
424
447
|
// during this batch. Runs after flushAvBridgePublishes so the BG mirror
|
|
425
448
|
// stays consistent with the styles we're about to commit.
|
|
426
449
|
flushAnimatedStyleBindings();
|
|
450
|
+
// Emit update-list-info diffs for any `<list>` whose children changed this
|
|
451
|
+
// batch, so native knows its cell count/keys before it lays out.
|
|
452
|
+
flushDirtyLists();
|
|
427
453
|
// Flush all pending PAPI changes to the native layer in one shot.
|
|
428
454
|
__FlushElementTree();
|
|
429
455
|
}
|
|
@@ -442,6 +468,7 @@ export function resetMainThreadState() {
|
|
|
442
468
|
lastTreeByElementWvid.clear();
|
|
443
469
|
elementIdByWvid.clear();
|
|
444
470
|
resetAnimatedStyleBindings();
|
|
471
|
+
resetListState();
|
|
445
472
|
// Clear upstream's worklet ref map too on hard reset (HMR / test).
|
|
446
473
|
const impl = globalThis['lynxWorkletImpl'];
|
|
447
474
|
if (impl?._refImpl)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sigx/lynx-runtime-main",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"description": "Main Thread (Lepus) entry and ops applier for SignalX Lynx renderer",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"url": "https://github.com/signalxjs/lynx/issues"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@sigx/lynx-runtime-internal": "0.4.
|
|
45
|
+
"@sigx/lynx-runtime-internal": "0.4.5"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"@lynx-js/types": ">=3.0.0"
|