@symbiote-native/vue 0.4.0 → 0.5.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 +6 -6
- package/build/bootstrap.js +1 -1
- package/build/components/flat-list/index.js +14 -5
- package/build/components/image-background.js +4 -5
- package/build/components/image.js +3 -1
- package/build/components/keyboard-avoiding-view.js +39 -14
- package/build/components/modal/index.js +5 -2
- package/build/components/pressable.d.ts +1 -1
- package/build/components/pressable.js +1 -1
- package/build/components/scroll-view/index.android.d.ts +1 -1
- package/build/components/scroll-view/index.android.js +3 -1
- package/build/components/scroll-view/index.ios.d.ts +1 -1
- package/build/components/scroll-view/index.ios.js +3 -1
- package/build/components/scroll-view/shared.js +33 -13
- package/build/components/scroll-view/sticky-header.js +18 -5
- package/build/components/section-list/index.js +4 -2
- package/build/components/switch/shared.js +12 -3
- package/build/components/text-input/index.js +7 -2
- package/build/components/touchable-native-feedback.js +3 -1
- package/build/components/touchable.d.ts +7 -1
- package/build/components/touchable.js +181 -33
- package/build/components/virtualized-list/index.js +42 -20
- package/build/components/virtualized-section-list/index.d.ts +5 -0
- package/build/components/virtualized-section-list/index.js +33 -4
- package/build/components.js +8 -3
- package/build/create-portal/index.d.ts +28 -0
- package/build/create-portal/index.js +42 -0
- package/build/host-instance/index.js +3 -1
- package/build/index.d.ts +8 -6
- package/build/index.js +9 -3
- package/build/modules/animated/create-animated-component.js +12 -4
- package/build/modules/animated/index.d.ts +2 -0
- package/build/modules/animated/index.js +18 -5
- package/build/modules/app-registry/index.js +4 -2
- package/build/modules/status-bar.js +4 -2
- package/build/render.d.ts +3 -1
- package/build/render.js +62 -1
- package/build/runtime-helpers/index.d.ts +44 -24
- package/build/runtime-helpers/index.js +107 -28
- package/build/utils/normalize-attrs.js +3 -1
- package/metro-vue-transformer.cjs +138 -97
- package/package.json +5 -5
|
@@ -23,15 +23,13 @@ registerTS(() => require('typescript'));
|
|
|
23
23
|
// Required directly (not via the ./metro-css-parser public subpath, which exists for CONSUMERS)
|
|
24
24
|
// so it resolves from this package's own node_modules under pnpm.
|
|
25
25
|
const {
|
|
26
|
-
classTokensIn,
|
|
27
26
|
compile: compilePreprocessor,
|
|
28
27
|
compileCssFile,
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
compileCssModule,
|
|
29
|
+
compileCssToRules,
|
|
30
|
+
compileScopedCss,
|
|
31
31
|
hashFilePath,
|
|
32
32
|
isStyleFile,
|
|
33
|
-
kebabToCamel,
|
|
34
|
-
parseCSS,
|
|
35
33
|
resolveUpstreamTransformer,
|
|
36
34
|
} = require('@symbiote-native/css-parser');
|
|
37
35
|
|
|
@@ -53,36 +51,43 @@ const compileScriptFs = {
|
|
|
53
51
|
},
|
|
54
52
|
};
|
|
55
53
|
|
|
56
|
-
// Rewrites a Vue template AST so every `class`/`:class` binding
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
//
|
|
54
|
+
// Rewrites a Vue template AST so every `class`/`:class` binding names a class by the name
|
|
55
|
+
// lightningcss RENAMED it to. AST-level, not a raw-text regex: Vue merges a static class= and a
|
|
56
|
+
// dynamic :class= on the same element into ONE codegen entry, and text substitution can't
|
|
57
|
+
// reproduce that merge safely - letting Vue's own transformElement do the merge on our rewritten
|
|
58
|
+
// nodes reuses that logic.
|
|
59
|
+
//
|
|
60
|
+
// `renames` is compileScopedCss's own name map (authored name -> renamed name), NOT a set of
|
|
61
|
+
// names this file re-suffixes. That is the point of the migration: the rewriter and the style
|
|
62
|
+
// compiler used to derive the scoped name independently, so any disagreement between them was
|
|
63
|
+
// silent. Now there is one source and this half only reads it. One entry per class, keyed as
|
|
64
|
+
// AUTHORED — `class="section-label"` is the lookup, `sectionLabel` is not a second spelling of it.
|
|
61
65
|
//
|
|
62
66
|
// A static class="foo bar" (AttributeNode, prop.type === 6) resolves to its final string here
|
|
63
|
-
// at compile time - no runtime call needed.
|
|
64
|
-
// css
|
|
67
|
+
// at compile time - no runtime call needed. A token the map does not carry belongs to another
|
|
68
|
+
// file (App.css, a `:global()` escape hatch, a parent's class) and passes through untouched.
|
|
65
69
|
//
|
|
66
70
|
// A dynamic :class="expr" (bind DirectiveNode, prop.type === 7) targeting `class`: by the time
|
|
67
71
|
// our transform runs, Vue's own transformExpression has already turned prop.exp into either a
|
|
68
72
|
// COMPOUND_EXPRESSION (type 8) or, for a bare identifier binding, a SIMPLE_EXPRESSION (type 4).
|
|
69
73
|
// createCompoundExpression wraps the original exp node as-is inside
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
function createScopeClassNodeTransform(
|
|
74
|
+
// renameClassTokens(<original>, __scopedClassNames), so codegen reproduces the original
|
|
75
|
+
// expression unchanged - no per-shape branching needed, and a fully opaque runtime value
|
|
76
|
+
// (`:class="dynamicClass"`) still resolves against the same map at runtime.
|
|
77
|
+
function createScopeClassNodeTransform(renames) {
|
|
74
78
|
return function scopeClassNodeTransform(node) {
|
|
75
79
|
if (node.type !== 1 /* NodeTypes.ELEMENT */) return;
|
|
76
80
|
|
|
77
81
|
for (const prop of node.props) {
|
|
78
|
-
if (
|
|
82
|
+
if (
|
|
83
|
+
prop.type === 6 /* NodeTypes.ATTRIBUTE */ &&
|
|
84
|
+
prop.name === 'class' &&
|
|
85
|
+
prop.value
|
|
86
|
+
) {
|
|
79
87
|
prop.value.content = prop.value.content
|
|
80
88
|
.split(/\s+/)
|
|
81
89
|
.filter(Boolean)
|
|
82
|
-
.map(token =>
|
|
83
|
-
const camelToken = kebabToCamel(token);
|
|
84
|
-
return localNames.has(camelToken) ? `${camelToken}__${scopeId}` : camelToken;
|
|
85
|
-
})
|
|
90
|
+
.map(token => renames.get(token) ?? token)
|
|
86
91
|
.join(' ');
|
|
87
92
|
continue;
|
|
88
93
|
}
|
|
@@ -96,7 +101,7 @@ function createScopeClassNodeTransform(localNames, scopeId) {
|
|
|
96
101
|
prop.exp
|
|
97
102
|
) {
|
|
98
103
|
prop.exp = createCompoundExpression(
|
|
99
|
-
['__scopeClass(', prop.exp, ',
|
|
104
|
+
['__scopeClass(', prop.exp, ', __scopedClassNames)'],
|
|
100
105
|
prop.exp.loc,
|
|
101
106
|
);
|
|
102
107
|
}
|
|
@@ -111,6 +116,35 @@ function scopeIdFor(filename) {
|
|
|
111
116
|
return 'data-v-' + hashFilePath(filename);
|
|
112
117
|
}
|
|
113
118
|
|
|
119
|
+
// The local the compiled component lands in when a <style module> block needs __cssModules hung
|
|
120
|
+
// off it (compileScript's genDefaultAs). Same role as @vitejs/plugin-vue's own `_sfc_main`.
|
|
121
|
+
const SFC_COMPONENT_VAR = '__sfc__';
|
|
122
|
+
|
|
123
|
+
// Blocks CONCATENATE - each is compiled on its own, so every block's rules restart at order 0 and
|
|
124
|
+
// a later block would tie with an earlier one on the cascade's source-order tie-break, silently
|
|
125
|
+
// reordering equally-specific rules. Renumbering on append gives the file one monotonic sequence,
|
|
126
|
+
// which is what a single stylesheet holding the concatenated blocks would have produced.
|
|
127
|
+
function appendRules(target, rules) {
|
|
128
|
+
for (const rule of rules) {
|
|
129
|
+
target.push({ ...rule, order: target.length });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// `combinators` is compile-time-only - the registry matches a rule by token SUBSET and never reads
|
|
134
|
+
// it - so it is stripped rather than shipped in every app bundle. Twin of css-parser's own
|
|
135
|
+
// serializeRules (core/css-parser/src/metro-css-module/index.ts), which does this for a standalone
|
|
136
|
+
// style file.
|
|
137
|
+
function serializeRules(rules) {
|
|
138
|
+
return JSON.stringify(
|
|
139
|
+
rules.map(({ tokens, specificity, order, style }) => ({
|
|
140
|
+
tokens,
|
|
141
|
+
specificity,
|
|
142
|
+
order,
|
|
143
|
+
style,
|
|
144
|
+
})),
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
114
148
|
// An SFC style block's `lang` attribute names a preprocessor language directly (`lang="scss"`),
|
|
115
149
|
// unlike a standalone file, which is identified by its extension — so this is its own small
|
|
116
150
|
// lookup rather than reusing detectLanguage(), which is extension-keyed.
|
|
@@ -128,7 +162,9 @@ async function compileStyleBlockContent(style, filename) {
|
|
|
128
162
|
|
|
129
163
|
const preprocessorLang = SFC_STYLE_LANG_TO_PREPROCESSOR.get(style.lang);
|
|
130
164
|
if (!preprocessorLang) {
|
|
131
|
-
throw new Error(
|
|
165
|
+
throw new Error(
|
|
166
|
+
`SFC style lang="${style.lang}" not supported yet — plain CSS only`,
|
|
167
|
+
);
|
|
132
168
|
}
|
|
133
169
|
|
|
134
170
|
// Sass' `.sass` indented syntax and `.scss` syntax share one compiler entry point that picks
|
|
@@ -143,10 +179,14 @@ async function compileStyleBlockContent(style, filename) {
|
|
|
143
179
|
async function compileSfc(src, filename) {
|
|
144
180
|
const { descriptor, errors } = parse(src, { filename });
|
|
145
181
|
if (errors && errors.length > 0) {
|
|
146
|
-
throw new Error(
|
|
182
|
+
throw new Error(
|
|
183
|
+
`Vue SFC parse error in ${filename}:\n${errors.map(String).join('\n')}`,
|
|
184
|
+
);
|
|
147
185
|
}
|
|
148
186
|
if (descriptor.scriptSetup == null && descriptor.script == null) {
|
|
149
|
-
throw new Error(
|
|
187
|
+
throw new Error(
|
|
188
|
+
`Vue SFC ${filename} has no <script> / <script setup> block`,
|
|
189
|
+
);
|
|
150
190
|
}
|
|
151
191
|
|
|
152
192
|
const scopeId = scopeIdFor(filename);
|
|
@@ -154,93 +194,82 @@ async function compileSfc(src, filename) {
|
|
|
154
194
|
// descriptor.styles is already parsed by @vue/compiler-sfc (one entry per <style> block,
|
|
155
195
|
// content pre-trimmed, scoped as a plain boolean) - no need to re-extract with a regex.
|
|
156
196
|
//
|
|
157
|
-
//
|
|
158
|
-
//
|
|
159
|
-
//
|
|
160
|
-
//
|
|
161
|
-
//
|
|
197
|
+
// Both scoped forms are ONE mechanism, lightningcss's CSS-Modules renaming, differing only in
|
|
198
|
+
// the pattern string (core/css-parser/src/scoped-classes.ts):
|
|
199
|
+
//
|
|
200
|
+
// <style scoped> [local]__data-v-<hash> compileScopedCss - `.card` -> `card__data-v-h`
|
|
201
|
+
// <style module> [local]__module__<hash> compileCssModule - the same call a standalone
|
|
202
|
+
// .module.css takes, so the two cannot diverge
|
|
203
|
+
// <style> not renamed at all compileCssToRules, classes register globally
|
|
204
|
+
//
|
|
205
|
+
// Renaming is our equivalent of Vue's `data-v-hash` ATTRIBUTE (we have no DOM and no
|
|
206
|
+
// attribute-selector matching, so a scope can only be expressed in the name), and `:global(...)`
|
|
207
|
+
// needs no handling here at all: a name lightningcss did not rename is global by definition.
|
|
162
208
|
//
|
|
163
|
-
// Multiple blocks cascade last-block-wins, same as CSS, after each block is scoped
|
|
209
|
+
// Multiple blocks cascade last-block-wins, same as CSS, after each block is scoped
|
|
210
|
+
// independently — carried by the rules' `order`, which appendRules renumbers across blocks.
|
|
164
211
|
//
|
|
165
|
-
//
|
|
166
|
-
//
|
|
167
|
-
//
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
// class="..." (opt-in via $style.x only), so they're kept out of localScopedNames. The
|
|
171
|
-
// registry key gets an extra `module` tag (`card__module__<scopeId>` vs scoped's
|
|
172
|
-
// `card__<scopeId>`) so a file mixing both kinds can't collide.
|
|
173
|
-
const styles = {};
|
|
174
|
-
const localScopedNames = new Set();
|
|
212
|
+
// A module block's classes are NEVER auto-applied to a literal class="..." (opt-in via $style.x
|
|
213
|
+
// only), so they stay out of the template rewriter's name map; its output is the name->scopedName
|
|
214
|
+
// map instead, emitted as a preamble const AND attached to the component as __cssModules.
|
|
215
|
+
const rules = [];
|
|
216
|
+
const scopedClassNames = new Map();
|
|
175
217
|
const cssModuleBindings = new Map();
|
|
176
218
|
|
|
177
219
|
for (const style of descriptor.styles) {
|
|
178
|
-
// Reduces a preprocessor block to plain CSS BEFORE the
|
|
179
|
-
//
|
|
220
|
+
// Reduces a preprocessor block to plain CSS BEFORE the renaming below runs - the renaming is
|
|
221
|
+
// language-agnostic, it only ever sees plain CSS.
|
|
180
222
|
const content = await compileStyleBlockContent(style, filename);
|
|
181
|
-
const parsed = parseCSS(content, { filename });
|
|
182
223
|
|
|
183
224
|
if (style.module) {
|
|
184
|
-
const bindingName =
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
classMap[className] = registeredName;
|
|
193
|
-
styles[registeredName] = { ...styles[registeredName], ...props };
|
|
194
|
-
}
|
|
195
|
-
cssModuleBindings.set(bindingName, classMap);
|
|
225
|
+
const bindingName =
|
|
226
|
+
typeof style.module === 'string' ? style.module : '$style';
|
|
227
|
+
const compiled = compileCssModule(content, filename);
|
|
228
|
+
appendRules(rules, compiled.rules);
|
|
229
|
+
cssModuleBindings.set(bindingName, {
|
|
230
|
+
...cssModuleBindings.get(bindingName),
|
|
231
|
+
...compiled.classMap,
|
|
232
|
+
});
|
|
196
233
|
} else if (style.scoped) {
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
// `.card :global(.reset)` the KEY (`cardReset`) is this file's own, because `.card` is,
|
|
205
|
-
// but `reset` was written precisely to name markup this file does not own. Suffixing it
|
|
206
|
-
// along with the rest of its chain scope-mangles the escape hatch into matching nothing.
|
|
207
|
-
const globalTokens = globalClassTokensIn(content, { filename });
|
|
208
|
-
for (const [className, props] of Object.entries(parsed)) {
|
|
209
|
-
const isExempt = exemptFromScope.has(className);
|
|
210
|
-
const registeredName = isExempt ? className : `${className}__${scopeId}`;
|
|
211
|
-
if (!isExempt) {
|
|
212
|
-
localScopedNames.add(className);
|
|
213
|
-
for (const token of tokensByName.get(className) ?? []) {
|
|
214
|
-
if (!globalTokens.has(token)) localScopedNames.add(token);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
styles[registeredName] = { ...styles[registeredName], ...props };
|
|
218
|
-
}
|
|
234
|
+
const compiled = compileScopedCss(content, {
|
|
235
|
+
filename,
|
|
236
|
+
pattern: `[local]__${scopeId}`,
|
|
237
|
+
});
|
|
238
|
+
appendRules(rules, compiled.rules);
|
|
239
|
+
for (const [name, renamed] of compiled.names)
|
|
240
|
+
scopedClassNames.set(name, renamed);
|
|
219
241
|
} else {
|
|
220
|
-
|
|
221
|
-
styles[className] = { ...styles[className], ...props };
|
|
222
|
-
}
|
|
242
|
+
appendRules(rules, compileCssToRules(content, { filename }).rules);
|
|
223
243
|
}
|
|
224
244
|
}
|
|
225
245
|
|
|
226
246
|
// Skipped entirely (not even passed to the compiler) when nothing in this file is scoped, so
|
|
227
247
|
// a .vue with only unscoped/no styles compiles with zero added runtime cost.
|
|
228
248
|
const templateOptions =
|
|
229
|
-
|
|
249
|
+
scopedClassNames.size > 0
|
|
230
250
|
? {
|
|
231
251
|
compilerOptions: {
|
|
232
|
-
nodeTransforms: [createScopeClassNodeTransform(
|
|
252
|
+
nodeTransforms: [createScopeClassNodeTransform(scopedClassNames)],
|
|
233
253
|
},
|
|
234
254
|
}
|
|
235
255
|
: undefined;
|
|
236
256
|
|
|
237
257
|
// inlineTemplate folds the <template> render fn into setup(): one module, one `export
|
|
238
258
|
// default`. Only valid with <script setup>, which the canary uses.
|
|
259
|
+
//
|
|
260
|
+
// genDefaultAs turns that `export default {...}` into `const __sfc__ = {...}`, so a <style
|
|
261
|
+
// module> block can hang __cssModules off the component OPTIONS object before the module
|
|
262
|
+
// exports it (the same thing @vitejs/plugin-vue does). Vue resolves a template's `$style` /
|
|
263
|
+
// `classes` off `instance.type.__cssModules`, NOT off module scope, so without this the
|
|
264
|
+
// emitted const is unreachable from the template and `$style.card` throws at render. Only
|
|
265
|
+
// requested when a module block exists, so every other .vue file keeps identical output.
|
|
266
|
+
const hasCssModules = cssModuleBindings.size > 0;
|
|
239
267
|
const compiled = compileScript(descriptor, {
|
|
240
268
|
id: scopeId,
|
|
241
269
|
inlineTemplate: true,
|
|
242
270
|
templateOptions,
|
|
243
271
|
fs: compileScriptFs,
|
|
272
|
+
...(hasCssModules ? { genDefaultAs: SFC_COMPONENT_VAR } : {}),
|
|
244
273
|
});
|
|
245
274
|
// Retargets every Vue import (compiler-injected helpers AND the user's own `from 'vue'`) at
|
|
246
275
|
// the runtime-helpers shim - no vue/runtime-dom in a native bundle.
|
|
@@ -249,35 +278,47 @@ async function compileSfc(src, filename) {
|
|
|
249
278
|
'from "@symbiote-native/vue/runtime-helpers"',
|
|
250
279
|
);
|
|
251
280
|
|
|
252
|
-
if (
|
|
281
|
+
if (rules.length === 0 && !hasCssModules) return code;
|
|
253
282
|
|
|
254
|
-
// Only a scoped file needs
|
|
283
|
+
// Only a scoped file needs the runtime rename helper and its per-file map, so these stay
|
|
255
284
|
// unimported for every non-scoped .vue file.
|
|
256
285
|
const engineImports =
|
|
257
|
-
|
|
286
|
+
scopedClassNames.size > 0
|
|
287
|
+
? 'registerRules, renameClassTokens as __scopeClass'
|
|
288
|
+
: 'registerRules';
|
|
258
289
|
|
|
259
|
-
const preamble = [
|
|
260
|
-
|
|
290
|
+
const preamble = [
|
|
291
|
+
`import { ${engineImports} } from '@symbiote-native/engine';`,
|
|
292
|
+
`registerRules(${serializeRules(rules)});`,
|
|
293
|
+
];
|
|
294
|
+
if (scopedClassNames.size > 0) {
|
|
261
295
|
preamble.push(
|
|
262
|
-
`const
|
|
263
|
-
`const __scopeId = ${JSON.stringify(scopeId)};`,
|
|
296
|
+
`const __scopedClassNames = ${JSON.stringify(Object.fromEntries(scopedClassNames))};`,
|
|
264
297
|
);
|
|
265
298
|
}
|
|
266
299
|
// Each <style module> binding becomes a top-level const holding its name->scopedName map,
|
|
267
|
-
// placed before the
|
|
268
|
-
//
|
|
300
|
+
// placed before the component so it's a closed-over module-scope variable usable from
|
|
301
|
+
// <script setup> code itself; the __cssModules tail below is what makes the TEMPLATE see it.
|
|
269
302
|
for (const [bindingName, classMap] of cssModuleBindings) {
|
|
270
303
|
preamble.push(`const ${bindingName} = ${JSON.stringify(classMap)};`);
|
|
271
304
|
}
|
|
272
305
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
306
|
+
const parts = [...preamble, code];
|
|
307
|
+
if (hasCssModules) {
|
|
308
|
+
const bindings = [...cssModuleBindings.keys()]
|
|
309
|
+
.map(name => `${JSON.stringify(name)}: ${name}`)
|
|
310
|
+
.join(', ');
|
|
311
|
+
parts.push(
|
|
312
|
+
`${SFC_COMPONENT_VAR}.__cssModules = { ${bindings} };`,
|
|
313
|
+
`export default ${SFC_COMPONENT_VAR};`,
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return parts.join('\n') + '\n';
|
|
277
318
|
}
|
|
278
319
|
|
|
279
320
|
// Exported separately from `transform` so tests can assert on the compiled SFC output
|
|
280
|
-
// (imports, injected `
|
|
321
|
+
// (imports, injected `registerRules` call) without driving the full upstream RN Babel preset.
|
|
281
322
|
module.exports.compileSfc = compileSfc;
|
|
282
323
|
|
|
283
324
|
// Async uniformly, including branches that never touch a preprocessor: compileSfc() itself is
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbiote-native/vue",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "SymbioteNative's Vue adapter — a @vue/runtime-core createRenderer driving real native iOS/Android views through the same engine as the React adapter.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"@vue/compiler-sfc": "^3.5.13",
|
|
47
47
|
"@vue/runtime-core": "^3.5.13",
|
|
48
48
|
"typescript": "~6.0.0",
|
|
49
|
-
"@symbiote-native/components": "0.
|
|
50
|
-
"@symbiote-native/css-parser": "0.
|
|
49
|
+
"@symbiote-native/components": "0.5.0",
|
|
50
|
+
"@symbiote-native/css-parser": "0.4.0"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"@symbiote-native/engine": ">=0.1.7",
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
"react-native": ">=0.86"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@symbiote-native/engine": "0.
|
|
59
|
-
"@symbiote-native/test-utils": "0.
|
|
58
|
+
"@symbiote-native/engine": "0.3.0",
|
|
59
|
+
"@symbiote-native/test-utils": "0.2.0"
|
|
60
60
|
},
|
|
61
61
|
"scripts": {
|
|
62
62
|
"typecheck": "tsc --build",
|