Skip to content

Commit

Permalink
[Data] Improvements to collection data logic
Browse files Browse the repository at this point in the history
[Dev] Improvements to DEV configuration
  • Loading branch information
Pckool committed Aug 22, 2022
1 parent 0b86eee commit d783921
Show file tree
Hide file tree
Showing 8 changed files with 452 additions and 343 deletions.
14 changes: 8 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@
"@testing-library/react": "^13.3.0",
"@types/jest": "^27.4.0",
"@types/node": "^17.0.8",
"@types/react": "^18.0.15",
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6",
"@types/react-test-renderer": "^18.0.0",
"@vitejs/plugin-react": "^1.3.2",
"@vitest/ui": "^0.17.1",
"@vitejs/plugin-react": "^2.0.1",
"@vitest/ui": "^0.22.1",
"babel-jest": "^27.4.6",
"happy-dom": "^6.0.2",
"happy-dom": "^6.0.4",
"husky": "^7.0.4",
"jest": "^27.4.7",
"jsdom": "^20.0.0",
Expand All @@ -45,12 +46,13 @@
"nodemon": "^2.0.15",
"nx": "^14.4.2",
"pinst": "^2.1.6",
"react-dom": "^18.2.0",
"react-dom": "^18",
"react-test-renderer": "^18.2.0",
"ts-jest": "^27.1.2",
"ts-node": "^10.4.0",
"typescript": "^4.5.4",
"vitest": "^0.17.1"
"vite": "^3.0.9",
"vitest": "^0.22.1"
},
"workspaces": {
"packages": [
Expand Down
12 changes: 7 additions & 5 deletions packages/plexus-core/src/collection/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ export class CollectionInstance<DataType, Groups extends GroupMap<DataType>, Sel
() => this.instance(),
() => this,
this._internalStore._key,
dataKey,
item
)
// if we get a valid data instance, add it to the collection
Expand Down Expand Up @@ -213,7 +214,7 @@ export class CollectionInstance<DataType, Groups extends GroupMap<DataType>, Sel
return this
}
/**
* Get the Value of the data item with the provided key (the raw data).
* Get the Value of the data item with the provided key (the raw data). If there is not an existing data item, this will return a _provisional_ one
* @param key
* @returns
*/
Expand All @@ -224,18 +225,19 @@ export class CollectionInstance<DataType, Groups extends GroupMap<DataType>, Sel
() => this.instance(),
() => this,
this._internalStore._key,
dataKey,
this.config.unfoundKeyReturnsUndefined
? (undefined as any as DataType)
: ({ [this._internalStore._key]: dataKey } as any as DataType),
{ prov: true, unfoundKeyIsUndefined: this.config.unfoundKeyReturnsUndefined }
)
// if we get a valid data instance, add it to the collection
// if (dataInstance) {
// this._internalStore._data.set(dataKey, dataInstance)
// }
if (dataInstance) {
this._internalStore._data.set(dataKey, dataInstance)
}
return dataInstance as PlexusDataInstance<DataType>
}
this.mount()
// this.mount()
return data
}
/**
Expand Down
58 changes: 33 additions & 25 deletions packages/plexus-core/src/collection/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ interface CollectionDataConfig {
unfoundKeyIsUndefined?: boolean
}
interface PlexusDataStore<DataType extends Record<string, any>> {
_key: string | number
primaryKey: string
_wDestroyers: Set<() => void>
_config: CollectionDataConfig
Expand All @@ -23,32 +22,33 @@ export type DataKey = string | number
// TODO: Remove the State Instance from the Data Instance's internalStore in favor of watchableValue's internalStore & logic
type DataObjectType<PK extends string = "id"> = Record<string, any> & { [Key in PK]: DataKey }
export class CollectionDataInstance<DataType extends DataObjectType<PK> = any, PK extends string = string> extends WatchableMutable<DataType> {
// private instance: () => PlexusInstance
primaryKey: PK
private primaryKey: PK
readonly key: string | number
provisional: boolean | undefined
private _internalStore: PlexusDataStore<DataType>

constructor(
instance: () => PlexusInstance,
public collection: () => PlexusCollectionInstance<DataType>,
primaryKey: PK,
keyValue: string | number,
value: DataType,
config: CollectionDataConfig = { prov: false }
) {
super(instance, value)
// this.instance = instance
this.provisional = config.prov
this.primaryKey = primaryKey
this.key = keyValue

this._internalStore = {
_key: value ? value[primaryKey] : value,
primaryKey,
_wDestroyers: new Set<() => void>(),
_config: config,
}
// this.value = value
if (!config.prov) {
if (!this.provisional) {
this.mount()
}

if (config.unfoundKeyIsUndefined) {
}
}
/**
* The internal id of the state with an instance prefix
Expand All @@ -72,16 +72,21 @@ export class CollectionDataInstance<DataType extends DataObjectType<PK> = any, P
}
}

private checkIfHasKey(value: Partial<DataType>) {
private checkIfHasKey(value?: Partial<DataType>): boolean {
// if the value is undefined/null
if (!value || !value[this._internalStore.primaryKey as PK]) {
return false
}
console.log(value)
// Check if the value has the primary key, and verify the key is the same as the data instance
const isCurrentKey = value?.[this._internalStore.primaryKey as PK].toString().trim() === this._internalStore._key.toString().trim()
const isCurrentKey = value[this._internalStore.primaryKey as PK].toString().trim() === this.key.toString().trim()
// if the key is not the same, then we can't use this value
const valid = value?.[this._internalStore.primaryKey] !== undefined && isCurrentKey
const valid = value[this._internalStore.primaryKey] !== undefined && isCurrentKey
this.instance().runtime.log(
"warn",
`The incoming value key does ${valid ? "" : "NOT"} match the stored key...`,
this._internalStore._key,
value?.[this._internalStore.primaryKey] === this._internalStore._key
this.key,
value[this._internalStore.primaryKey] === this.key
)
return valid
}
Expand Down Expand Up @@ -110,21 +115,24 @@ export class CollectionDataInstance<DataType extends DataObjectType<PK> = any, P
set(value?: Partial<DataType>) {
if (!value) return this

// maybe this check should be done inside of the state?
// if this is provisional, mount to the collection & instance
if (!!this.provisional) {
this.instance().runtime.log("debug", `Mounting provisional data instance "${this.key}" to instance...`)
this.mount()
this.provisional = undefined
}
if (!isEqual(value as DataType, this.value)) {
if (this.checkIfHasKey(value)) {
// this._internalStore._state.set(value as DataType)
super.set(value as DataType)
}
// give the id to the new value if it's missing
super.set({ ...value, [this.primaryKey]: this.value[this.primaryKey] } as DataType)
super.set({ ...value, [this.primaryKey]: this.key } as DataType)
} else {
this.instance().runtime.log(
"warn",
`Tried applying the same value to data "${this.value[this.primaryKey]}" in collection ${this.collection().id}...`
)
this.instance().runtime.log("warn", `Tried applying the same value to data "${this.key}" in collection ${this.collection().id}...`)
}
this.collection().lastUpdatedKey = this._internalStore._key
this.collection().lastUpdatedKey = this.key

return this
}
/**
Expand All @@ -137,7 +145,7 @@ export class CollectionDataInstance<DataType extends DataObjectType<PK> = any, P
// }
this.set(deepMerge(this._watchableStore._value, value))

this.collection().lastUpdatedKey = this._internalStore._key
this.collection().lastUpdatedKey = this.key
return this
}

Expand All @@ -154,7 +162,7 @@ export class CollectionDataInstance<DataType extends DataObjectType<PK> = any, P
*/
delete() {
// this.instance().runtime.removeWatchers("state", this._internalStore._state.name)
this.collection().delete(this._internalStore._key)
this.collection().delete(this.key)

// delete _internalStore._state
}
Expand All @@ -173,7 +181,6 @@ export class CollectionDataInstance<DataType extends DataObjectType<PK> = any, P
* @returns The remove function to stop watching
*/
watch(callback: PlexusWatcher<DataType>, from?: string) {
// const destroyer = this._internalStore._state.watch(callback)
const destroyer = super.watch(callback, from)
return destroyer
}
Expand All @@ -183,11 +190,12 @@ export function _data<DataType extends Record<string, any>>(
instance: () => PlexusInstance,
collection: () => PlexusCollectionInstance<DataType>,
primaryKey: string,
keyValue: number | string,
value: DataType,
config: CollectionDataConfig = { prov: false }
) {
if ((value?.[primaryKey] !== undefined && value?.[primaryKey] !== null) || config.prov) {
return new CollectionDataInstance(instance, collection, primaryKey, value, config)
return new CollectionDataInstance(instance, collection, primaryKey, keyValue, value, config)
}
return null
}
13 changes: 13 additions & 0 deletions tests/collection.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,4 +347,17 @@ describe("Testing Collection", () => {
expect(myCollection.value.length).toBe(3)
expect(myCollection.getSelector("main").value.thing).toBe("lol2")
})

test("Can a provisional Data item stay reactive", () => {
console.log("Check...")
instance({ logLevel: "debug" })
myCollection.getItem(15).watch((v) => {
console.log(`new data`, v)
})
console.log(myCollection.getItem(15).value)
myCollection.getItem(15).set({ thing: "provisional no more" })
console.log("wtf")
console.log(myCollection.getItem(15).value)
instance({ logLevel: undefined })
})
})
Loading

0 comments on commit d783921

Please sign in to comment.