Skip to content

Commit

Permalink
fix: Make dependencies (ModuleProxy) actually optional (#2750)
Browse files Browse the repository at this point in the history
fix: Make dependencies actually optional
  • Loading branch information
mrousavy authored Apr 18, 2024
1 parent b751f2d commit c3098db
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 14 deletions.
4 changes: 2 additions & 2 deletions package/example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ PODS:
- RCT-Folly (= 2021.07.22.00)
- React-Core
- SocketRocket (0.6.1)
- VisionCamera (4.0.0-beta.14):
- VisionCamera (4.0.0-beta.15):
- React
- React-callinvoker
- React-Core
Expand Down Expand Up @@ -701,7 +701,7 @@ SPEC CHECKSUMS:
RNStaticSafeAreaInsets: 055ddbf5e476321720457cdaeec0ff2ba40ec1b8
RNVectorIcons: 23b6e11af4aaf104d169b1b0afa7e5cf96c676ce
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
VisionCamera: 4d01ac25d09288d3aa670b1e0eb092c47e7d4211
VisionCamera: 6f2f2b7e9df333899e640e3617bc02cac86f4774
Yoga: 4c3aa327e4a6a23eeacd71f61c81df1bcdf677d5

PODFILE CHECKSUM: 299b350392623e1b01615935e236438d90fd2cff
Expand Down
16 changes: 10 additions & 6 deletions package/src/dependencies/ModuleProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,24 @@ type ImportType = ReturnType<typeof require>
* Create a lazily-imported module proxy.
* This is useful for lazily requiring optional dependencies.
*/
export const createModuleProxy = <TModule>(name: string, getModule: () => ImportType): TModule => {
export const createModuleProxy = <TModule>(getModule: () => ImportType): TModule => {
const holder: { module: TModule | undefined } = { module: undefined }

const proxy = new Proxy(holder, {
get: (target, property) => {
if (target.module == null) {
try {
target.module = getModule() as TModule
} catch (e) {
throw new Error(`${name} is not installed!`)
}
// lazy initialize module via require()
// caller needs to make sure the require() call is wrapped in a try/catch
target.module = getModule() as TModule
}
return target.module[property as keyof typeof holder.module]
},
})
return proxy as unknown as TModule
}

export class OptionalDependencyNotInstalledError extends Error {
constructor(name: string) {
super(`${name} is not installed!`)
}
}
11 changes: 9 additions & 2 deletions package/src/dependencies/ReanimatedProxy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type * as Reanimated from 'react-native-reanimated'
import { createModuleProxy } from './ModuleProxy'
import { createModuleProxy, OptionalDependencyNotInstalledError } from './ModuleProxy'

type TReanimated = typeof Reanimated

/**
Expand All @@ -9,4 +10,10 @@ type TReanimated = typeof Reanimated
* If react-native-reanimated is not installed, accessing anything on
* {@linkcode ReanimatedProxy} will throw.
*/
export const ReanimatedProxy = createModuleProxy<TReanimated>('react-native-reanimated', () => require('react-native-reanimated'))
export const ReanimatedProxy = createModuleProxy<TReanimated>(() => {
try {
return require('react-native-reanimated')
} catch (e) {
throw new OptionalDependencyNotInstalledError('react-native-reanimated')
}
})
11 changes: 9 additions & 2 deletions package/src/dependencies/SkiaProxy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type * as Skia from '@shopify/react-native-skia'
import { createModuleProxy } from './ModuleProxy'
import { createModuleProxy, OptionalDependencyNotInstalledError } from './ModuleProxy'

type TSkia = typeof Skia

/**
Expand All @@ -9,4 +10,10 @@ type TSkia = typeof Skia
* If @shopify/react-native-skia is not installed, accessing anything on
* {@linkcode SkiaProxy} will throw.
*/
export const SkiaProxy = createModuleProxy<TSkia>('@shopify/react-native-skia', () => require('@shopify/react-native-skia'))
export const SkiaProxy = createModuleProxy<TSkia>(() => {
try {
return require('@shopify/react-native-skia')
} catch (e) {
throw new OptionalDependencyNotInstalledError('@shopify/react-native-skia')
}
})
11 changes: 9 additions & 2 deletions package/src/dependencies/WorkletsProxy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type * as Worklets from 'react-native-worklets-core'
import { createModuleProxy } from './ModuleProxy'
import { createModuleProxy, OptionalDependencyNotInstalledError } from './ModuleProxy'

type TWorklets = typeof Worklets

/**
Expand All @@ -9,4 +10,10 @@ type TWorklets = typeof Worklets
* If react-native-worklets-core is not installed, accessing anything on
* {@linkcode WorkletsProxy} will throw.
*/
export const WorkletsProxy = createModuleProxy<TWorklets>('react-native-worklets-core', () => require('react-native-worklets-core'))
export const WorkletsProxy = createModuleProxy<TWorklets>(() => {
try {
return require('react-native-worklets-core')
} catch (e) {
throw new OptionalDependencyNotInstalledError('react-native-worklets-core')
}
})

0 comments on commit c3098db

Please sign in to comment.