Skip to content

Commit 55a0c5e

Browse files
committed
3.10.2 bump
1 parent 8b9e316 commit 55a0c5e

File tree

11 files changed

+191
-27
lines changed

11 files changed

+191
-27
lines changed

examples/reactnative/App.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import React from 'react';
22
import flagsmith from 'react-native-flagsmith';
3-
import {FlagsmithProvider} from 'flagsmith/react';
3+
import {FlagsmithProvider} from 'react-native-flagsmith/react';
44
import AsyncStorage from '@react-native-async-storage/async-storage';
55
import AppComponent from './ExampleComponent';
66

7-
87
export default function () {
98
return (
109
<FlagsmithProvider

examples/reactnative/ExampleComponent.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import React, {useCallback, useEffect} from 'react';
2-
import {useFlags, useFlagsmith} from 'flagsmith/react';
1+
import React, {useCallback} from 'react';
2+
import {useFlags, useFlagsmith} from 'react-native-flagsmith/react';
33
import {Text, TouchableOpacity, View} from 'react-native';
44
function ExampleComponent() {
55
const flags = useFlags(['font_size'], ['example_trait']); // only causes re-render if specified flag values / traits change

examples/reactnative/package-lock.json

Lines changed: 7 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/reactnative/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@
1111
},
1212
"dependencies": {
1313
"@react-native-async-storage/async-storage": "^1.17.0",
14-
"flagsmith": "3.9.2",
1514
"react": "17.0.2",
1615
"react-native": "0.67.4",
17-
"react-native-flagsmith": "3.9.2"
16+
"react-native-flagsmith": "3.10.2"
1817
},
1918
"devDependencies": {
2019
"@babel/core": "7.17.8",

lib/flagsmith/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "flagsmith",
3-
"version": "3.10.1",
3+
"version": "3.10.2",
44
"description": "Feature flagging to support continuous development",
55
"main": "./index.js",
66
"repository": {

lib/react-native-flagsmith/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-flagsmith",
3-
"version": "3.10.1",
3+
"version": "3.10.2",
44
"description": "Feature flagging to support continuous development",
55
"main": "./index.js",
66
"repository": {

lib/react-native-flagsmith/react.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React, { FC } from 'react';
2+
import { IFlagsmith, IFlagsmithTrait, IFlagsmithFeature, IState } from '../types';
3+
export declare const FlagsmithContext: React.Context<IFlagsmith>;
4+
export declare type FlagsmithContextType<F extends string = string, T extends string = string> = {
5+
flagsmith: IFlagsmith<F, T>;
6+
options?: Parameters<IFlagsmith<F, T>['init']>[0];
7+
serverState?: IState<F, T>;
8+
children: React.ReactElement[] | React.ReactElement;
9+
};
10+
export declare const FlagsmithProvider: FC<FlagsmithContextType>;
11+
export declare function useFlags<F extends string, T extends string>(_flags: readonly F[], _traits?: readonly T[]): {
12+
[K in F]: IFlagsmithFeature;
13+
} & {
14+
[K in T]: IFlagsmithTrait;
15+
};
16+
export declare const useFlagsmith: () => IFlagsmith;
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import React, {
2+
createContext, FC,
3+
useCallback,
4+
useContext,
5+
useEffect,
6+
useMemo,
7+
useRef,
8+
useState,
9+
} from 'react'
10+
import Emitter from 'tiny-emitter';
11+
const events = new Emitter.TinyEmitter();
12+
13+
import {IFlagsmith, IFlagsmithTrait, IFlagsmithFeature, IState} from './types'
14+
15+
export const FlagsmithContext = createContext<IFlagsmith<string,string> | null>(null)
16+
export type FlagsmithContextType = {
17+
flagsmith: IFlagsmith // The flagsmith instance
18+
options?: Parameters<IFlagsmith['init']>[0] // Initialisation options, if you do not provide this you will have to call init manually
19+
serverState?: IState
20+
children: React.ReactElement[] | React.ReactElement;
21+
}
22+
23+
export const FlagsmithProvider: FC<FlagsmithContextType> = ({
24+
flagsmith, options, serverState, children,
25+
}) => {
26+
const firstRenderRef = useRef(true)
27+
if (serverState && !flagsmith.initialised) {
28+
flagsmith.setState(serverState)
29+
}
30+
if (firstRenderRef.current) {
31+
firstRenderRef.current = false
32+
if (options) {
33+
flagsmith.init({
34+
...options,
35+
onChange: (...args) => {
36+
if (options.onChange) {
37+
options.onChange(...args)
38+
}
39+
events.emit('event')
40+
},
41+
})
42+
} else {
43+
flagsmith.trigger = ()=>events.emit('event');
44+
}
45+
}
46+
return (
47+
<FlagsmithContext.Provider value={flagsmith}>
48+
{children}
49+
</FlagsmithContext.Provider>
50+
)
51+
}
52+
53+
const useConstant = function <T>(value: T): T {
54+
const ref = useRef(value)
55+
if (!ref.current) {
56+
ref.current = value
57+
}
58+
return ref.current
59+
}
60+
61+
62+
const flagsAsArray = (_flags: any): string[] => {
63+
if (typeof _flags === 'string') {
64+
return [_flags]
65+
} else if (typeof _flags === 'object') {
66+
// eslint-disable-next-line no-prototype-builtins
67+
if (_flags.hasOwnProperty('length')) {
68+
return _flags
69+
}
70+
}
71+
throw new Error(
72+
'Flagsmith: please supply an array of strings or a single string of flag keys to useFlags',
73+
)
74+
}
75+
76+
const getRenderKey = (flagsmith: IFlagsmith, flags: string[], traits: string[] = []) => {
77+
return flags
78+
.map((k) => {
79+
return `${flagsmith.getValue(k)}${flagsmith.hasFeature(k)}`
80+
}).concat(traits.map((t) => (
81+
`${flagsmith.getTrait(t)}`
82+
)))
83+
.join(',')
84+
}
85+
86+
export function useFlags<F extends string=string, T extends string=string>(_flags: readonly F[], _traits: readonly T[] = []): {
87+
[K in F]: IFlagsmithFeature
88+
} & {
89+
[K in T]: IFlagsmithTrait
90+
} {
91+
const flags = useConstant<string[]>(flagsAsArray(_flags))
92+
const traits = useConstant<string[]>(flagsAsArray(_traits))
93+
const flagsmith = useContext(FlagsmithContext)
94+
const [renderKey, setRenderKey] = useState<string>(
95+
getRenderKey(flagsmith as IFlagsmith, flags),
96+
)
97+
const renderRef = useRef<string>(renderKey)
98+
const eventListener = useCallback(() => {
99+
const newRenderKey = getRenderKey(flagsmith as IFlagsmith, flags, traits)
100+
if (newRenderKey !== renderRef.current) {
101+
renderRef.current = newRenderKey
102+
setRenderKey(newRenderKey)
103+
}
104+
}, [])
105+
useEffect(() => {
106+
events.on('event', eventListener)
107+
return () => {
108+
events.off('event', eventListener)
109+
}
110+
}, [])
111+
const res = useMemo(() => {
112+
const res: any = {}
113+
flags.map((k) => {
114+
res[k] = {
115+
enabled: flagsmith!.hasFeature(k),
116+
value: flagsmith!.getValue(k),
117+
}
118+
}).concat(traits?.map((v) => {
119+
res[v] = flagsmith!.getTrait(v)
120+
}))
121+
return res
122+
}, [renderKey])
123+
124+
return res
125+
}
126+
127+
export function useFlagsmith<F extends string=string, T extends string=string>() {
128+
const context = useContext(FlagsmithContext)
129+
130+
if (!context) {
131+
throw new Error('useFlagsmith must be used with in a FlagsmithProvider')
132+
}
133+
134+
return context as IFlagsmith<F,T>
135+
}

move-react.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ fs.copyFileSync(path.join(__dirname,"flagsmith-core.ts"),path.join(__dirname,"li
2424
fs.copyFileSync(path.join(__dirname,"next-middleware.ts"),path.join(__dirname,"lib/flagsmith/src/next-middleware.ts"))
2525
fs.copyFileSync(path.join(__dirname,"isomorphic.ts"),path.join(__dirname,"lib/flagsmith/src/isomorphic.ts"))
2626
fs.copyFileSync(path.join(__dirname,"react.tsx"),path.join(__dirname,"lib/flagsmith/src/react.tsx"))
27+
fs.copyFileSync(path.join(__dirname,"react.tsx"),path.join(__dirname,"lib/react-native-flagsmith/src/react.tsx"))
28+
fs.copyFileSync(path.join(__dirname,"react.d.ts"),path.join(__dirname,"lib/react-native-flagsmith/src/react.d.ts"))
2729
//Remove not needed flagsmith-core.d.ts
2830
fs.rmSync(path.join(__dirname,"lib/flagsmith/flagsmith-core.d.ts"))
2931
fs.rmSync(path.join(__dirname,"lib/react-native-flagsmith/flagsmith-core.d.ts"))
@@ -82,6 +84,7 @@ replaceInFileSync(path.join(__dirname, "lib/react-native-flagsmith/index.js.map"
8284

8385
// fix paths in flagsmith/react.js sourcemaps
8486
replaceInFileSync(path.join(__dirname, "lib/flagsmith/react.js.map"),"../../../react.tsx","./src/react.tsx" )
87+
replaceInFileSync(path.join(__dirname, "lib/react-native-flagsmith/react.js.map"),"../../../react.tsx","./src/react.tsx" )
8588

8689
// fix paths in flagsmith-es/react.js sourcemaps
8790
replaceInFileSync(path.join(__dirname, "lib/flagsmith-es/react.js.map"),"../../../react.tsx","./src/react.tsx" )

0 commit comments

Comments
 (0)