Comparing version 1.0.9 to 1.0.10
{ | ||
"name": "drifting", | ||
"version": "1.0.9", | ||
"version": "1.0.10", | ||
"description": "A fully typescript typed react solution for interacting with complex data-structures", | ||
@@ -9,3 +9,4 @@ "main": "lib/index.js", | ||
"test:watch": "yarn jest --watchAll", | ||
"build": "rimraf ./lib && tsc" | ||
"build": "rimraf ./lib && tsc", | ||
"build:watch": "rimraf ./lib && tsc --watch true" | ||
}, | ||
@@ -31,16 +32,16 @@ "repository": { | ||
"devDependencies": { | ||
"@testing-library/react-hooks": "3.4.2", | ||
"@types/jest": "26.0.15", | ||
"@types/react": "16.14.0", | ||
"@types/react-dom": "16.9.9", | ||
"@testing-library/react-hooks": "3.7.0", | ||
"@types/jest": "26.0.19", | ||
"@types/react": "17.0.0", | ||
"@types/react-dom": "17.0.0", | ||
"jest": "26.6.3", | ||
"react-test-renderer": "17.0.1", | ||
"ts-jest": "26.4.4", | ||
"typescript": "4.0.5" | ||
"typescript": "4.1.3" | ||
}, | ||
"dependencies": { | ||
"immer": "8.0.0", | ||
"react": "17.0.1", | ||
"react-dom": "17.0.1" | ||
"react": "16.14.0", | ||
"react-dom": "16.14.0" | ||
} | ||
} |
@@ -1,5 +0,5 @@ | ||
import { renderHook, act } from '@testing-library/react-hooks' | ||
import { act, renderHook } from '@testing-library/react-hooks' | ||
import { useData } from '..' | ||
const record = { | ||
@@ -205,3 +205,28 @@ type: 'user', | ||
}) | ||
it('should be possible to return a new slice when using select', () => { | ||
const rec = { | ||
type: 'budget' , | ||
attributes: { | ||
name: 'test', | ||
info: { | ||
status: 'online' | ||
} | ||
} | ||
} | ||
const { result } = renderHook(() => useData(rec)) | ||
const [, ctrl] = result.current | ||
const [, attrCtrl] = ctrl.select((record) => record.attributes) | ||
const [, infoCtrl] = attrCtrl.select((attributes) => attributes.info) | ||
act(() => { | ||
infoCtrl.update(() => ({ status: 'offline' })) | ||
}) | ||
const record = result.current[0] | ||
expect(record.attributes.info.status).toBe('offline') | ||
}) | ||
}) | ||
}) |
@@ -1,34 +0,39 @@ | ||
import { useState, useEffect, useMemo } from 'react' | ||
import produce, { Draft } from 'immer' | ||
import { useEffect, useMemo, useState } from 'react' | ||
type AnyFunction = (...args: any[]) => any | ||
type Updater<G> = (draft: Draft<G>) => Draft<G>|undefined|void | ||
type Slice<T extends AnyFunction> = T extends (...args: any[]) => infer R | ||
? R | ||
: never | ||
function copy<T extends Record<string, any>> (obj1: T, obj2: T) { | ||
for (let key in obj1) { | ||
obj1[key] = obj2[key] | ||
} | ||
} | ||
type UpdateCb<G> = (args: Draft<G>) => G|void|undefined | ||
function createSelect<G> (data: G, onUpdate: (updater: (draft: Draft<G>) => void) => void) { | ||
return <T>(selector: (data: G) => T) => { | ||
const selectedState = selector(data) | ||
function createReturnedTuple<G> (nextDataState: G, updateFn: (cb: UpdateCb<G>) => void) { | ||
return <T extends (slice: G) => any>(getSelected: T) => { | ||
const selectedDataState: Slice<T> = getSelected(nextDataState) | ||
const update = (updater: Updater<T>) => ( | ||
onUpdate((draft) => { | ||
const selectedDraft = selector(draft as G) as Draft<T> | ||
const result = updater(selectedDraft) | ||
const update = (updateSelected: UpdateCb<Slice<T>>) => ( | ||
updateFn((draft) => updateSelected(getSelected(draft as G))) | ||
if (result) { | ||
copy(selectedDraft, result) | ||
} | ||
}) | ||
) | ||
return [ | ||
selectedDataState, | ||
selectedState, | ||
{ | ||
/** | ||
* @description | ||
* Use .update() to make mutations, like with immer, to your data structure. | ||
* .update() uses [produce from immerjs](https://immerjs.github.io/immer/docs/produce) to allow you to mutate your state in a pure way. | ||
* @example | ||
* const [record, { update }] useData(data) | ||
* | ||
* update((record) => { | ||
* record.attributes.status = 'successful' | ||
* record.attributes.info = 'some value...' | ||
* }) | ||
*/ | ||
* ```typescript | ||
* [[include:update.example.ts]] | ||
* ``` | ||
*/ | ||
update, | ||
@@ -39,7 +44,7 @@ /** | ||
* @example | ||
* const [record, { select }] useData(data) | ||
* | ||
* const [attributes, { update }] = select(record => record.atributes) | ||
*/ | ||
select: createReturnedTuple<Slice<T>>(selectedDataState, update) | ||
* ```typescript | ||
* [[include:select.example.ts]] | ||
* ``` | ||
*/ | ||
select: createSelect(selectedState, update) | ||
} | ||
@@ -53,14 +58,11 @@ ] as const | ||
export function useData<T extends Data = Record<string, unknown>> (data: T) { | ||
const [nextDataState, setDataState] = useState<T>(data) | ||
const [state, setState] = useState(data) | ||
useEffect(() => { | ||
setDataState(data) | ||
}, [data]) | ||
useEffect(() => void setState(data), [data]) | ||
return useMemo(() => { | ||
return createReturnedTuple( | ||
nextDataState, | ||
(updater) => void (setDataState(produce(nextDataState, updater) as T)) | ||
)(data => data) | ||
}, [nextDataState]) | ||
const rootSelect = createSelect(state, (updater) => setState(produce(state, updater))) | ||
return rootSelect(data => data) | ||
}, [state]) | ||
} |
@@ -8,3 +8,2 @@ { | ||
/* Strict Type-Checking Options */ | ||
@@ -22,6 +21,9 @@ "strict": true, /* Enable all strict type-checking options. */ | ||
"skipLibCheck": true, /* Skip type checking of declaration files. */ | ||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ | ||
"forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */ | ||
"pretty": true | ||
}, | ||
"include": [ | ||
"src" | ||
"src", | ||
"examples" | ||
], | ||
@@ -28,0 +30,0 @@ "exclude": [ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
36981
24
817
1
+ Addedprop-types@15.8.1(transitive)
+ Addedreact@16.14.0(transitive)
+ Addedreact-dom@16.14.0(transitive)
+ Addedreact-is@16.13.1(transitive)
+ Addedscheduler@0.19.1(transitive)
- Removedreact@17.0.1(transitive)
- Removedreact-dom@17.0.1(transitive)
- Removedscheduler@0.20.2(transitive)
Updatedreact@16.14.0
Updatedreact-dom@16.14.0