react-native-impeller-platform 0.0.0-stage → 0.3.1

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.
Files changed (39) hide show
  1. package/README.md +165 -2
  2. package/package.json +52 -4
  3. package/react-native.config.js +24 -0
  4. package/src/bin/engine-path.js +12 -0
  5. package/src/cli/index.js +20 -0
  6. package/src/cli/init.js +112 -0
  7. package/src/cli/run.js +73 -0
  8. package/src/externaltexture/index.js +58 -0
  9. package/src/index.js +12 -0
  10. package/src/metro-shims/index.js +382 -0
  11. package/src/metro-shims/shims/Alert.impeller.js +89 -0
  12. package/src/metro-shims/shims/BaseViewConfig.impeller.js +81 -0
  13. package/src/metro-shims/shims/Button.impeller.js +100 -0
  14. package/src/metro-shims/shims/Image.impeller.js +97 -0
  15. package/src/metro-shims/shims/Platform.impeller-as-ios.js +44 -0
  16. package/src/metro-shims/shims/Platform.impeller.js +53 -0
  17. package/src/metro-shims/shims/ReactNativeFeatureFlags.impeller.js +40 -0
  18. package/src/metro-shims/shims/ReactNativeStyleAttributes.impeller.js +20 -0
  19. package/src/metro-shims/shims/TextInputState.impeller.js +100 -0
  20. package/src/metro-shims/shims/ViewConfigIgnore.impeller.js +55 -0
  21. package/src/metro-shims/shims/reanimated/clock.js +41 -0
  22. package/src/metro-shims/shims/reanimated/component.js +83 -0
  23. package/src/metro-shims/shims/reanimated/css.js +193 -0
  24. package/src/metro-shims/shims/reanimated/easing.js +47 -0
  25. package/src/metro-shims/shims/reanimated/hooks.js +191 -0
  26. package/src/metro-shims/shims/reanimated/interpolate.js +133 -0
  27. package/src/metro-shims/shims/reanimated/values.js +264 -0
  28. package/src/metro-shims/shims/reanimated.impeller.js +90 -0
  29. package/src/notifications/index.d.ts +44 -0
  30. package/src/notifications/index.js +95 -0
  31. package/src/platformview/index.js +23 -0
  32. package/src/resolve.js +238 -0
  33. package/src/selftest.js +123 -0
  34. package/src/storage/index.js +161 -0
  35. package/src/viewshot/index.js +98 -0
  36. package/src/worldraster/index.js +75 -0
  37. package/templates/app/README.md.tmpl +18 -0
  38. package/templates/app/_gitignore +1 -0
  39. package/templates/app/impeller.config.json.tmpl +11 -0
package/README.md CHANGED
@@ -1,3 +1,166 @@
1
- # Temporary Holding Version
1
+ # react-native-impeller-platform
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ An out-of-tree React Native platform whose renderer is
4
+ [Impeller](https://github.com/flutter/engine/tree/main/impeller), Flutter's
5
+ graphics engine. React components mount through Fabric into a scene graph that
6
+ Impeller paints — no DOM, no native view hierarchy, no per-platform UI toolkit.
7
+
8
+ **Status: pre-release, and honest about it.** The rendering, the JS↔native
9
+ module seam and the packaging are gated by pixel tests on every commit, but the
10
+ API surface is small and the published platform list is short. See "Supported
11
+ platforms" before installing.
12
+
13
+ ## Install
14
+
15
+ > **Not published yet.** These packages are configured to publish **publicly**,
16
+ > but nothing has been released to npm — publishing stays deliberately gated
17
+ > while the API settles. Until the first release, install from a git checkout or
18
+ > a packed tarball. The command below will work once a version ships.
19
+
20
+ ```bash
21
+ npm install react-native-impeller-platform
22
+ ```
23
+
24
+ The engine binary is not in this package. It installs automatically as an
25
+ optional dependency matching your platform and architecture.
26
+
27
+ ## Supported platforms
28
+
29
+ | Platform | Engine package | Status |
30
+ |---|---|---|
31
+ | linux-x64 | `@blbaker/react-native-impeller-platform-engine-linux-x64` | builds + renders |
32
+ | win32-x64 | `@blbaker/react-native-impeller-platform-engine-win32-x64` | builds + renders |
33
+ | darwin-arm64 | `@blbaker/react-native-impeller-platform-engine-darwin-arm64` | builds + renders |
34
+ | darwin-x64, linux-arm64 | — | not started |
35
+
36
+ Nothing is on npm yet — see Install. "builds + renders" means the engine
37
+ package exists, installs into an app outside the repo, and puts correct pixels
38
+ on screen there (P1 consumer + P2 mount + P3 conformance + P4 module seam).
39
+
40
+ **A platform is listed only once its engine package actually exists.** npm
41
+ silently skips a missing optional dependency and exits 0, so declaring a
42
+ platform we cannot ship would give you a clean install with no engine — and
43
+ then an error telling you to install a package that does not exist.
44
+
45
+ If your platform is not listed, it is not supported yet. `resolveEngine` says so
46
+ directly rather than failing obscurely at runtime.
47
+
48
+ ## Not published yet — what that means for you
49
+
50
+ Until the first release lands on npm there is no consumer story, and this
51
+ README will not pretend otherwise. **Do not build the engine to use this
52
+ package.** Compiling Hermes from source, installing Xcode and cmake, packing
53
+ tarballs by hand, or running a local registry are all things a *contributor to
54
+ this repo* does. A consumer runs `npm install` and nothing else.
55
+
56
+ If you want to use `react-native-impeller-platform` in an app today, the honest
57
+ answer is: wait for the release. The install above is the entire intended
58
+ experience, and it is one command deliberately — the engine arrives as an
59
+ optional dependency selected by your platform, with no build step, no native
60
+ toolchain, and no environment variables.
61
+
62
+ `IMPELLER_ENGINE_BINARY` exists for engine development, not for consumption. If
63
+ you find yourself setting it in an app, something is wrong with the package and
64
+ that is a bug worth reporting.
65
+
66
+ ---
67
+
68
+ # Contributing to this repo
69
+
70
+ Everything below is for working ON react-native-impeller-platform. None of it is
71
+ required — or appropriate — for using the published package.
72
+
73
+ ## Installing it locally, before the first npm release
74
+
75
+ You can consume the package on this machine exactly the way a published install
76
+ works — `npm install react-native-impeller-platform`, no flags, no env vars, no
77
+ build step in the consuming app — with a throwaway local registry:
78
+
79
+ ```bash
80
+ npx verdaccio --listen 127.0.0.1:4873
81
+ cd package && npm publish --registry http://127.0.0.1:4873
82
+ cd ../packages-engine/engine-$(node -p 'process.platform+"-"+process.arch') \
83
+ && npm publish --registry http://127.0.0.1:4873
84
+
85
+ # in a scratch app — exactly what a published install will look like
86
+ npm install react-native-impeller-platform --registry http://127.0.0.1:4873
87
+ ```
88
+
89
+ Keep `--registry` on that one command instead of writing it into the app's
90
+ `.npmrc`. A global `registry=` line routes the app's entire dependency graph
91
+ through a throwaway server, which is a supply-chain change nobody asked for. A
92
+ scoped line (`@blbaker:registry=http://127.0.0.1:4873`)
93
+ only covers the engine packages, because the main package is unscoped.
94
+
95
+ Bump the version in every `package.json` before re-publishing; a registry
96
+ refuses to overwrite an existing version, the same as npmjs.
97
+
98
+ (Baker's own dev loop also keeps a *persistent* local registry running via a
99
+ systemd/launchd unit and a wrapper script, so he doesn't have to repeat the
100
+ steps above on every rebuild. That wrapper and its unit files are specific to
101
+ his machines and aren't included in this public copy; the commands above are
102
+ the portable, manual equivalent.)
103
+
104
+ ## Building the engine
105
+
106
+ ```bash
107
+ bash tools/engine-build.sh <platform> <arch> # e.g. darwin arm64
108
+ ```
109
+
110
+ Needs a C++ toolchain, `cmake`, `ninja` and Node 18+ (on macOS: full Xcode, not
111
+ just Command Line Tools). The first run compiles Hermes from source at the exact
112
+ tag React Native pins — budget ~40 minutes; later builds reuse it.
113
+
114
+ ## Testing the consumer experience
115
+
116
+ ```bash
117
+ bash tools/pack-and-consume.sh # installs packed tarballs into a pristine app
118
+ ```
119
+
120
+ Installing a tarball by path hand-places the package and **cannot** exercise
121
+ what a real user hits: npm reading `optionalDependencies` and selecting the
122
+ one engine whose `os`/`cpu` match. npm skips an optional dependency it cannot
123
+ use *and exits 0*, so every failure in that path is silent — `pack-and-consume.sh`
124
+ still only proves the by-path install. For the by-name, real-`npm publish`
125
+ version of this check (a by-name registry gate isn't part of this repo), use the manual verdaccio recipe above and check both that the
126
+ host's engine arrived and that no foreign-platform engine did.
127
+
128
+ ## Using a locally built engine (engine development only)
129
+
130
+ `IMPELLER_ENGINE_BINARY` points the resolver at a binary you built yourself:
131
+
132
+ ```bash
133
+ export IMPELLER_ENGINE_BINARY=/path/to/rn-impeller
134
+ ```
135
+
136
+ It takes priority over the installed engine package and skips the version
137
+ lockstep check.
138
+
139
+ > **This is not a consumer workaround.** It exists so engine developers can test
140
+ > a build without packing it. If a platform has no published engine package, the
141
+ > answer is to publish one — not to tell users to set an environment variable.
142
+ > A package that requires an env var to function has not shipped.
143
+
144
+ ## Versioning
145
+
146
+ The host package and every engine package are released in **lockstep at exactly
147
+ the same version**, and the resolver refuses a mismatched pair rather than
148
+ letting it fail at runtime:
149
+
150
+ ```
151
+ Engine version mismatch: @blbaker/react-native-impeller-platform-engine-linux-x64@0.0.2 is installed
152
+ but react-native-impeller-platform@0.0.1 requires exactly 0.0.1.
153
+ ```
154
+
155
+ The engine exposes a C ABI that is not stable across versions, so this is a hard
156
+ requirement, not a convention. Never pin an engine package with `^` or `~`;
157
+ `tools/ci-release-meta.sh` fails the build if a range appears.
158
+
159
+ ## Requirements
160
+
161
+ - Node.js >= 20
162
+ - React Native >= 0.86 (peer dependency)
163
+
164
+ ## License
165
+
166
+ MIT
package/package.json CHANGED
@@ -1,6 +1,54 @@
1
1
  {
2
2
  "name": "react-native-impeller-platform",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.3.1",
4
+ "description": "Out-of-tree React Native platform rendered with Flutter's Impeller engine",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/blbaker/react-native-impeller-platform.git",
9
+ "directory": "package"
10
+ },
11
+ "homepage": "https://blbaker.github.io/react-native-impeller-platform/",
12
+ "bugs": {
13
+ "url": "https://github.com/blbaker/react-native-impeller-platform/issues"
14
+ },
15
+ "author": "Brandon Baker",
16
+ "keywords": [
17
+ "react-native",
18
+ "react-native-platform",
19
+ "out-of-tree-platform",
20
+ "impeller",
21
+ "flutter",
22
+ "desktop",
23
+ "linux",
24
+ "macos",
25
+ "windows"
26
+ ],
27
+ "main": "src/index.js",
28
+ "files": [
29
+ "src",
30
+ "templates",
31
+ "react-native.config.js",
32
+ "README.md"
33
+ ],
34
+ "bin": {
35
+ "impeller-engine-path": "src/bin/engine-path.js"
36
+ },
37
+ "scripts": {
38
+ "test": "node src/selftest.js"
39
+ },
40
+ "peerDependencies": {
41
+ "react-native": ">=0.86.0"
42
+ },
43
+ "optionalDependencies": {
44
+ "@blbaker/react-native-impeller-platform-engine-darwin-arm64": "0.3.1",
45
+ "@blbaker/react-native-impeller-platform-engine-linux-x64": "0.3.1",
46
+ "@blbaker/react-native-impeller-platform-engine-win32-x64": "0.3.1"
47
+ },
48
+ "publishConfig": {
49
+ "access": "public"
50
+ },
51
+ "engines": {
52
+ "node": ">=20"
53
+ }
54
+ }
@@ -0,0 +1,24 @@
1
+ // CLI + platform registration for the `impeller` out-of-tree platform.
2
+ //
3
+ // PLAN D1: `npmPackageName` is deliberately NOT set. Setting it declares this
4
+ // package a react-native FORK and makes the CLI/Metro redirect InitializeCore into
5
+ // it -- the exact failure documented in the skia-platform packaging notes. This is
6
+ // an OVERLAY platform: it sits beside stock react-native.
7
+ const cli = require('./src/cli');
8
+
9
+ module.exports = {
10
+ commands: cli.commands,
11
+ platforms: {
12
+ impeller: {
13
+ linkConfig: () => ({
14
+ isInstalled: () => false,
15
+ register: () => {},
16
+ unregister: () => {},
17
+ copyAssets: () => {},
18
+ unlinkAssets: () => {},
19
+ }),
20
+ projectConfig: (root, userConfig) => (userConfig ? {...userConfig, root} : null),
21
+ dependencyConfig: () => null,
22
+ },
23
+ },
24
+ };
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ // Prints the resolved engine binary path, or a naming-the-package error on stderr.
4
+ // Used by CI gates and by consumers debugging an install.
5
+ const {resolveEngine} = require('../resolve');
6
+ try {
7
+ const r = resolveEngine();
8
+ process.stdout.write(r.binary + '\n');
9
+ } catch (e) {
10
+ process.stderr.write(e.message + '\n');
11
+ process.exit(1);
12
+ }
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+ const {initImpeller} = require('./init');
3
+ const {runImpeller} = require('./run');
4
+
5
+ const commands = [
6
+ {
7
+ name: 'init-impeller',
8
+ description: 'Scaffold the impeller/ folder into this React Native app',
9
+ options: [{name: '--force', description: 'Overwrite existing scaffolded files'}],
10
+ func: (argv, config, args) => initImpeller(argv, config, {force: Boolean(args && args.force)}),
11
+ },
12
+ {
13
+ name: 'run-impeller',
14
+ description: 'Bundle with Metro (platform=impeller) and launch the Impeller engine',
15
+ options: [{name: '--release', description: 'Build a production bundle'}],
16
+ func: (argv, config) => runImpeller(argv, config, {}),
17
+ },
18
+ ];
19
+
20
+ module.exports = {commands, initImpeller, runImpeller};
@@ -0,0 +1,112 @@
1
+ 'use strict';
2
+ // `npx react-native init-impeller`
3
+ //
4
+ // PLAN D5: SCAFFOLD, NOT HARDCODE. Everything app-specific is derived from the
5
+ // consumer's app.json/package.json at scaffold time. No "playground", no
6
+ // workspaceRoot, no monorepo assumptions, no CWD-relative runtime paths.
7
+
8
+ const fs = require('fs');
9
+ const path = require('path');
10
+
11
+ const TEMPLATE_DIR = path.join(__dirname, '..', '..', 'templates', 'app');
12
+
13
+ function readJson(p) {
14
+ return JSON.parse(fs.readFileSync(p, 'utf8'));
15
+ }
16
+
17
+ function detectAppName(root) {
18
+ const appJson = path.join(root, 'app.json');
19
+ if (fs.existsSync(appJson)) {
20
+ const j = readJson(appJson);
21
+ if (j.name) return j.name;
22
+ }
23
+ const pkgJson = path.join(root, 'package.json');
24
+ if (fs.existsSync(pkgJson)) {
25
+ const j = readJson(pkgJson);
26
+ if (j.name) return j.name;
27
+ }
28
+ throw new Error(
29
+ 'Cannot determine the app name: neither app.json nor package.json has a "name".\n' +
30
+ 'Run init-impeller from the root of a React Native app.'
31
+ );
32
+ }
33
+
34
+ function detectDisplayName(root, fallback) {
35
+ const appJson = path.join(root, 'app.json');
36
+ if (fs.existsSync(appJson)) {
37
+ const j = readJson(appJson);
38
+ if (j.displayName) return j.displayName;
39
+ }
40
+ return fallback;
41
+ }
42
+
43
+ function render(text, vars) {
44
+ return text.replace(/\{\{(\w+)\}\}/g, (m, k) => {
45
+ if (!(k in vars)) throw new Error(`Template references unknown variable {{${k}}}`);
46
+ return vars[k];
47
+ });
48
+ }
49
+
50
+ function copyTemplate(srcDir, destDir, vars, {force, log}) {
51
+ fs.mkdirSync(destDir, {recursive: true});
52
+ for (const entry of fs.readdirSync(srcDir, {withFileTypes: true})) {
53
+ const src = path.join(srcDir, entry.name);
54
+ const outName = entry.name.replace(/^_/, '.').replace(/\.tmpl$/, '');
55
+ const dest = path.join(destDir, outName);
56
+ if (entry.isDirectory()) {
57
+ copyTemplate(src, dest, vars, {force, log});
58
+ continue;
59
+ }
60
+ if (fs.existsSync(dest) && !force) {
61
+ log(` skip ${path.relative(process.cwd(), dest)} (exists, use --force)`);
62
+ continue;
63
+ }
64
+ fs.writeFileSync(dest, render(fs.readFileSync(src, 'utf8'), vars));
65
+ log(` write ${path.relative(process.cwd(), dest)}`);
66
+ }
67
+ }
68
+
69
+ function ensureMetroConfig(root, {log}) {
70
+ const p = path.join(root, 'metro.config.js');
71
+ const wrapped = `const {withImpeller} = require('react-native-impeller-platform/src/metro-shims');`;
72
+ if (!fs.existsSync(p)) {
73
+ fs.writeFileSync(
74
+ p,
75
+ `${wrapped}\nconst {getDefaultConfig} = require('@react-native/metro-config');\n\nmodule.exports = withImpeller(getDefaultConfig(__dirname));\n`
76
+ );
77
+ log(' write metro.config.js');
78
+ return;
79
+ }
80
+ const existing = fs.readFileSync(p, 'utf8');
81
+ if (existing.includes('withImpeller')) {
82
+ log(' ok metro.config.js already wraps withImpeller');
83
+ return;
84
+ }
85
+ // Wrap, do not replace: preserve whatever the app already exports.
86
+ const patched =
87
+ `${wrapped}\n` +
88
+ existing.replace(/module\.exports\s*=\s*/, 'const __impellerBase = ') +
89
+ `\nmodule.exports = withImpeller(__impellerBase);\n`;
90
+ fs.writeFileSync(p, patched);
91
+ log(' patch metro.config.js (wrapped existing export with withImpeller)');
92
+ }
93
+
94
+ function initImpeller(argv, config, options = {}) {
95
+ const root = (config && config.root) || process.cwd();
96
+ const log = options.log || console.log;
97
+ const force = Boolean(options.force);
98
+
99
+ const appName = detectAppName(root);
100
+ const vars = {
101
+ appName,
102
+ displayName: detectDisplayName(root, appName),
103
+ };
104
+
105
+ log(`init-impeller: scaffolding impeller/ for app "${appName}"`);
106
+ copyTemplate(TEMPLATE_DIR, path.join(root, 'impeller'), vars, {force, log});
107
+ ensureMetroConfig(root, {log});
108
+ log('Done. Next: npx react-native run-impeller');
109
+ return {appName, dir: path.join(root, 'impeller')};
110
+ }
111
+
112
+ module.exports = {initImpeller, detectAppName, render, TEMPLATE_DIR};
package/src/cli/run.js ADDED
@@ -0,0 +1,73 @@
1
+ 'use strict';
2
+ // `npx react-native run-impeller`
3
+ //
4
+ // Builds a bundle with Metro (platform=impeller) and launches the engine binary,
5
+ // passing the bundle as an ABSOLUTE path. PLAN D5: the engine has NO CWD probe and
6
+ // no fallback bundle location -- if the path is wrong we want a loud failure, not a
7
+ // stale bundle rendered from some other directory.
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+ const {spawnSync} = require('child_process');
12
+ const {resolveEngine} = require('../resolve');
13
+
14
+ function readAppConfig(root) {
15
+ const appJson = path.join(root, 'app.json');
16
+ if (fs.existsSync(appJson)) {
17
+ const j = JSON.parse(fs.readFileSync(appJson, 'utf8'));
18
+ if (j.name) return j;
19
+ }
20
+ const pkg = JSON.parse(fs.readFileSync(path.join(root, 'package.json'), 'utf8'));
21
+ return {name: pkg.name};
22
+ }
23
+
24
+ function bundle(root, {dev, entryFile, outDir, log, cliBin}) {
25
+ fs.mkdirSync(outDir, {recursive: true});
26
+ const out = path.join(outDir, 'index.impeller.bundle');
27
+ const args = [
28
+ cliBin || require.resolve('@react-native-community/cli/build/bin.js', {paths: [root]}),
29
+ 'bundle',
30
+ '--platform',
31
+ 'impeller',
32
+ '--dev',
33
+ String(Boolean(dev)),
34
+ '--entry-file',
35
+ entryFile,
36
+ '--bundle-output',
37
+ out,
38
+ '--assets-dest',
39
+ path.join(outDir, 'assets'),
40
+ ];
41
+ log(`bundling: node ${args.slice(1).join(' ')}`);
42
+ const r = spawnSync(process.execPath, args, {cwd: root, stdio: 'inherit'});
43
+ if (r.status !== 0) {
44
+ throw new Error(`Metro bundle failed with exit code ${r.status}`);
45
+ }
46
+ if (!fs.existsSync(out)) {
47
+ throw new Error(`Metro reported success but produced no bundle at ${out}`);
48
+ }
49
+ return out;
50
+ }
51
+
52
+ function runImpeller(argv = [], config, options = {}) {
53
+ const root = (config && config.root) || process.cwd();
54
+ const log = options.log || console.log;
55
+ const dev = !argv.includes('--release');
56
+ const entryFile = options.entryFile || 'index.js';
57
+ const outDir = path.join(root, 'impeller', 'build');
58
+
59
+ const app = readAppConfig(root);
60
+ const bundlePath = options.bundlePath || bundle(root, {dev, entryFile, outDir, log, cliBin: options.cliBin});
61
+ const {binary, source, packageName} = resolveEngine();
62
+ log(`engine: ${binary} (${source}${packageName ? ` -- ${packageName}` : ''})`);
63
+
64
+ const engineArgs = ['--bundle', path.resolve(bundlePath), '--app-name', app.name, ...argv.filter((a) => a !== '--release')];
65
+ if (options.dryRun) return {binary, engineArgs, bundlePath};
66
+
67
+ const r = spawnSync(binary, engineArgs, {cwd: root, stdio: 'inherit'});
68
+ if (r.error) throw r.error;
69
+ process.exitCode = r.status === null ? 1 : r.status;
70
+ return {binary, engineArgs, bundlePath, status: r.status};
71
+ }
72
+
73
+ module.exports = {runImpeller, bundle};
@@ -0,0 +1,58 @@
1
+ 'use strict';
2
+ // FP-42 — external textures (Flutter's Texture widget + TextureRegistry).
3
+ //
4
+ // <ImpellerTextureView textureId={id} style={...} /> paints the latest frame of
5
+ // the engine's texture `id` inside the view's clip, transform and opacity.
6
+ // Native producers (video, camera) register textures from C++; this module
7
+ // adds a test producer from JS. Same `get` (not `getEnforcing`) pattern as
8
+ // ../worldraster: an engine without the module fails only the calls that need it.
9
+
10
+ const {TurboModuleRegistry} = require('react-native');
11
+ const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
12
+
13
+ const Native = TurboModuleRegistry.get('ImpellerTextureRegistry');
14
+
15
+ function mod() {
16
+ if (Native == null) {
17
+ throw new Error(
18
+ 'ImpellerTextureRegistry native module is unavailable. The engine binary ' +
19
+ 'predates FP-42: external textures cannot work until the engine is updated.',
20
+ );
21
+ }
22
+ return Native;
23
+ }
24
+
25
+ function isSupported() {
26
+ return Native != null && mod().isSupported();
27
+ }
28
+
29
+ // A native animated test pattern at `fps`; returns its texture id. maxFrames > 0
30
+ // stops it after that many frames (the last one stays registered).
31
+ function registerTestProducer(fps, width, height, maxFrames = 0) {
32
+ return mod().registerTestProducer(fps, width, height, maxFrames);
33
+ }
34
+
35
+ // Stops painting `id` (views showing it paint nothing). False: unknown id.
36
+ function unregister(id) {
37
+ return mod().unregister(id);
38
+ }
39
+
40
+ // Tells the engine texture `id` has a new frame (native producers do this).
41
+ function markFrameAvailable(id) {
42
+ mod().markFrameAvailable(id);
43
+ }
44
+
45
+ const ImpellerTextureView = NativeComponentRegistry.get('ImpellerTextureView', () => ({
46
+ uiViewClassName: 'ImpellerTextureView',
47
+ bubblingEventTypes: {},
48
+ directEventTypes: {},
49
+ validAttributes: {textureId: true},
50
+ }));
51
+
52
+ module.exports = {
53
+ isSupported,
54
+ registerTestProducer,
55
+ unregister,
56
+ markFrameAvailable,
57
+ ImpellerTextureView,
58
+ };
package/src/index.js ADDED
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+ const {resolveEngine, hostTriple, packageNameFor} = require('./resolve');
3
+ const {withImpeller} = require('./metro-shims');
4
+ const cli = require('./cli');
5
+
6
+ module.exports = {
7
+ resolveEngine,
8
+ hostTriple,
9
+ packageNameFor,
10
+ withImpeller,
11
+ commands: cli.commands,
12
+ };