Skip to content
This repository was archived by the owner on Oct 16, 2024. It is now read-only.

Commit 7b90274

Browse files
authored
Merge pull request #181 from agile-ts/develop
'New Release 🎉
2 parents e6de997 + 21e913d commit 7b90274

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2345
-1995
lines changed

.changeset/strong-jars-occur.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
'@agile-ts/api': patch
3+
'@agile-ts/core': patch
4+
'@agile-ts/event': patch
5+
'@agile-ts/logger': patch
6+
'@agile-ts/multieditor': patch
7+
'@agile-ts/react': patch
8+
'@agile-ts/utils': patch
9+
---
10+
11+
#### :bug: Bug Fix
12+
* `core`
13+
* [#176](https://github.com/agile-ts/agile/pull/176) Fix persisting dynamically added items ([@bennodev19](https://github.com/bennodev19))
14+
15+
#### :nail_care: Polish
16+
* `api`, `core`, `event`, `logger`, `multieditor`, `react`, `utils`
17+
* [#177](https://github.com/agile-ts/agile/pull/177) Optimize default configurations ([@bennodev19](https://github.com/bennodev19))
18+
19+
#### Committers: 1
20+
- BennoDev ([@bennodev19](https://github.com/bennodev19))
21+

benchmark/benchmarks/react/counter/index.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,16 @@ const results: CycleResultInterface[] = [];
6464
// Add Tests to the Benchmark Test Suite
6565
suite
6666
.add('AgileTs', configTest(agilets))
67-
// .add('Hookstate', configTest(hookstate))
68-
// .add('Jotai', configTest(jotai))
69-
// .add('Mobx', configTest(mobx))
70-
// .add('Nano Stores', configTest(nanostores))
71-
// .add('PulseJs', configTest(pulsejs))
72-
// .add('Recoil', configTest(recoil))
73-
// .add('Redux', configTest(redux))
74-
// .add('Redux-Toolkit', configTest(reduxToolkit))
75-
// .add('Valtio', configTest(valtio))
76-
// .add('Zustand', configTest(zustand))
67+
.add('Hookstate', configTest(hookstate))
68+
.add('Jotai', configTest(jotai))
69+
.add('Mobx', configTest(mobx))
70+
.add('Nano Stores', configTest(nanostores))
71+
.add('PulseJs', configTest(pulsejs))
72+
.add('Recoil', configTest(recoil))
73+
.add('Redux', configTest(redux))
74+
.add('Redux-Toolkit', configTest(reduxToolkit))
75+
.add('Valtio', configTest(valtio))
76+
.add('Zustand', configTest(zustand))
7777

7878
// Add Listener
7979
.on('start', function (this: any) {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
export function defineConfig(
2+
config: any,
3+
defaults: any,
4+
overwriteUndefinedProperties?: boolean
5+
): any {
6+
if (overwriteUndefinedProperties === undefined)
7+
overwriteUndefinedProperties = true;
8+
9+
const shallowCopiedConfig = { ...config };
10+
11+
for (const defaultKey in defaults) {
12+
if (
13+
!Object.prototype.hasOwnProperty.call(shallowCopiedConfig, defaultKey) ||
14+
(overwriteUndefinedProperties &&
15+
shallowCopiedConfig[defaultKey] === undefined)
16+
)
17+
shallowCopiedConfig[defaultKey] = defaults[defaultKey];
18+
}
19+
20+
return shallowCopiedConfig;
21+
}

benchmark/benchmarks/typescript/defineConfig/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
// Files to run the Benchmark on
1111
import * as referencer from './bench/referencer';
1212
import * as spreader from './bench/spreader';
13+
import * as spreadReferencer from './bench/spreadReferencer';
1314

1415
interface ConfigInterface {
1516
x1?: boolean;
@@ -63,6 +64,16 @@ suite
6364
x5: 'hans',
6465
});
6566
})
67+
.add('SpreadReferencer', function () {
68+
let config = defaultConfig;
69+
config = spreadReferencer.defineConfig(config, {
70+
x1: false,
71+
x2: 'jeff',
72+
x3: 10,
73+
x4: false,
74+
x5: 'hans',
75+
});
76+
})
6677

6778
// Add Listener
6879
.on('start', function (this: any) {

package.json

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"watch:event": "cd packages/event && yarn run watch",
2828
"test": "jest --passWithNoTests",
2929
"test:coverage": "jest --coverage",
30+
"test:coverage:pushToCoveralls": "yarn run test:coverage && coveralls < coverage/lcov.info",
3031
"dev:publish": "lerna run build && lerna run dev:publish",
3132
"dev:push": "lerna run build && lerna run dev:push",
3233
"install:packages": "lerna exec yarn install",
@@ -46,30 +47,30 @@
4647
"url": "git+https://github.com/agile-ts/agile.git"
4748
},
4849
"devDependencies": {
49-
"@changesets/cli": "^2.12.0",
50-
"@size-limit/file": "^4.12.0",
51-
"@types/jest": "^26.0.15",
52-
"@types/node": "^14.14.7",
53-
"@typescript-eslint/eslint-plugin": "^4.12.0",
54-
"@typescript-eslint/parser": "^4.12.0",
55-
"coveralls": "^3.1.0",
56-
"eslint": "^7.17.0",
50+
"@changesets/cli": "^2.16.0",
51+
"@size-limit/file": "^5.0.1",
52+
"@types/jest": "^26.0.24",
53+
"@types/node": "^16.3.2",
54+
"@typescript-eslint/eslint-plugin": "^4.28.3",
55+
"@typescript-eslint/parser": "^4.28.3",
56+
"coveralls": "^3.1.1",
57+
"eslint": "^7.30.0",
5758
"eslint-config-node": "^4.1.0",
58-
"eslint-config-prettier": "^6.11.0",
59+
"eslint-config-prettier": "^8.3.0",
5960
"eslint-plugin-node": "^11.1.0",
60-
"eslint-plugin-prettier": "^3.3.1",
61+
"eslint-plugin-prettier": "^3.4.0",
6162
"jest": "^26.6.3",
62-
"jest-mock-console": "^1.0.1",
63-
"lerna": "^3.22.1",
63+
"jest-mock-console": "^1.1.0",
64+
"lerna": "^4.0.0",
6465
"lerna-changelog": "^1.0.1",
65-
"nodemon": "^2.0.6",
66-
"prettier": "2.1.2",
67-
"size-limit": "^4.12.0",
68-
"ts-jest": "^26.4.4",
69-
"ts-node": "^8.10.2",
70-
"tsc-watch": "^4.1.0",
71-
"tslib": "^2.0.0",
72-
"typescript": "^3.9.7",
66+
"nodemon": "^2.0.12",
67+
"prettier": "^2.3.2",
68+
"size-limit": "^5.0.1",
69+
"ts-jest": "^26.5.6",
70+
"ts-node": "^10.1.0",
71+
"tsc-watch": "^4.4.0",
72+
"tslib": "^2.3.0",
73+
"typescript": "^4.3.5",
7374
"wait-for-expect": "^3.0.2"
7475
},
7576
"workspaces": [

packages/api/src/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { clone, copy, isValidObject } from '@agile-ts/utils';
1+
import { clone, copy, defineConfig, isValidObject } from '@agile-ts/utils';
22

33
export default class API {
44
public config: ApiConfig;
@@ -21,7 +21,7 @@ export default class API {
2121
*/
2222
public with(config: ApiConfig = {}): API {
2323
const modifiedApi = clone(this);
24-
modifiedApi.config = { ...this.config, ...config };
24+
modifiedApi.config = defineConfig(config, this.config);
2525
return modifiedApi;
2626
}
2727

@@ -113,7 +113,7 @@ export default class API {
113113

114114
// Configure request Options
115115
const config = copy(this.config);
116-
config.options = { ...config.options, ...options };
116+
config.options = defineConfig(options, config.options || {});
117117
config.options.method = method;
118118
if (!config.options.headers) config.options.headers = {};
119119

packages/core/src/agile.ts

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
createCollection,
2525
createComputed,
2626
IntegrationsConfigInterface,
27+
defineConfig,
2728
} from './internal';
2829

2930
export class Agile {
@@ -72,14 +73,13 @@ export class Agile {
7273
* @param config - Configuration object
7374
*/
7475
constructor(config: CreateAgileConfigInterface = {}) {
75-
config = {
76+
config = defineConfig(config, {
7677
localStorage: false,
7778
waitForMount: true,
7879
bindGlobal: false,
7980
autoIntegrate: true,
8081
bucket: true,
81-
...config,
82-
};
82+
});
8383
this.config = {
8484
waitForMount: config.waitForMount as any,
8585
bucket: config.bucket as any,
@@ -143,10 +143,12 @@ export class Agile {
143143
initialValue: ValueType,
144144
config: StateConfigInterface = {}
145145
): State<ValueType> {
146-
return createState<ValueType>(initialValue, {
147-
...config,
148-
...{ agileInstance: this },
149-
});
146+
return createState<ValueType>(
147+
initialValue,
148+
defineConfig(config, {
149+
agileInstance: this,
150+
})
151+
);
150152
}
151153

152154
/**
@@ -226,13 +228,15 @@ export class Agile {
226228
let _config: CreateComputedConfigInterface = {};
227229

228230
if (Array.isArray(configOrDeps)) {
229-
_config = flatMerge(_config, {
231+
_config = defineConfig(_config, {
230232
computedDeps: configOrDeps,
231233
agileInstance: this,
232234
});
233235
} else {
234236
if (configOrDeps)
235-
_config = { ...configOrDeps, ...{ agileInstance: this } };
237+
_config = defineConfig(configOrDeps, {
238+
agileInstance: this,
239+
});
236240
}
237241

238242
return createComputed<ComputedValueType>(computeFunction, _config);

packages/core/src/collection/collection.persistent.ts

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
CollectionKey,
44
CreatePersistentConfigInterface,
55
DefaultItem,
6+
defineConfig,
67
Group,
78
GroupKey,
89
ItemKey,
@@ -36,12 +37,11 @@ export class CollectionPersistent<
3637
super(collection.agileInstance(), {
3738
instantiate: false,
3839
});
39-
config = {
40+
config = defineConfig(config, {
4041
instantiate: true,
4142
storageKeys: [],
4243
defaultStorageKey: null as any,
43-
...config,
44-
};
44+
});
4545
this.collection = () => collection;
4646
this.instantiatePersistent({
4747
key: config.key,
@@ -128,35 +128,49 @@ export class CollectionPersistent<
128128
_storageItemKey
129129
);
130130

131-
// Persist and therefore load already present Item
131+
// Persist an already present Item and load its value manually to be 100% sure
132+
// that it was loaded completely
132133
if (item != null) {
133134
item.persist(itemStorageKey, {
135+
loadValue: false,
134136
defaultStorageKey: this.config.defaultStorageKey || undefined,
135137
storageKeys: this.storageKeys,
136138
followCollectionPersistKeyPattern: false, // Because of the dynamic 'storageItemKey', the key is already formatted above
137139
});
140+
if (item?.persistent?.ready) await item.persistent.initialLoading();
138141
}
139-
// Persist and therefore load not present Item
142+
// Persist an already present placeholder Item
143+
// or create a new placeholder Item to load the value in
144+
// and load its value manually to be 100% sure
145+
// that it was loaded completely.
146+
// After a successful loading assign the now valid Item to the Collection.
140147
else {
141-
// Create temporary placeholder Item in which the Item value will be loaded
142-
const dummyItem = this.collection().createPlaceholderItem(itemKey);
143-
144-
// Persist dummy Item and load its value manually to be 100% sure
145-
// that it was loaded completely and exists at all
146-
dummyItem?.persist(itemStorageKey, {
148+
const placeholderItem = this.collection().getItemWithReference(
149+
itemKey
150+
);
151+
placeholderItem?.persist(itemStorageKey, {
147152
loadValue: false,
148153
defaultStorageKey: this.config.defaultStorageKey as any,
149154
storageKeys: this.storageKeys,
150155
followCollectionPersistKeyPattern: false, // Because of the dynamic 'storageItemKey', the key is already formatted above
151156
});
152-
if (dummyItem?.persistent?.ready) {
153-
const loadedPersistedValueIntoItem = await dummyItem.persistent.loadPersistedValue(
154-
itemStorageKey
155-
); // TODO FIRST GROUP REBUILD (by assigning loaded value to Item)
157+
if (placeholderItem?.persistent?.ready) {
158+
const loadedPersistedValueIntoItem = await placeholderItem.persistent.loadPersistedValue(); // TODO FIRST GROUP REBUILD (by assigning loaded value to Item)
156159

157160
// If successfully loaded Item value, assign Item to Collection
158-
if (loadedPersistedValueIntoItem)
159-
this.collection().assignItem(dummyItem, { overwrite: false }); // TODO SECOND GROUP REBUILD (by calling rebuildGroupThatInclude() in the assignItem() method)
161+
if (loadedPersistedValueIntoItem) {
162+
this.collection().assignItem(placeholderItem, {
163+
overwrite: true, // Overwrite to overwrite the existing placeholder Item, if one exists
164+
}); // TODO SECOND GROUP REBUILD (by calling rebuildGroupThatInclude() in the assignItem() method)
165+
166+
placeholderItem.isPersisted = true;
167+
168+
// Manually increase Collection size,
169+
// since these Items already exist in the Collection (because of 'getItemWithReference()')
170+
// but were placeholder before the persisted value got loaded
171+
// -> Collection size wasn't increased in 'assignItem()'
172+
this.collection().size += 1;
173+
}
160174
}
161175
}
162176
}

packages/core/src/collection/group/group.observer.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
Item,
1010
IngestConfigInterface,
1111
CreateRuntimeJobConfigInterface,
12+
defineConfig,
1213
} from '../../internal';
1314

1415
export class GroupObserver<DataType = any> extends Observer {
@@ -31,7 +32,10 @@ export class GroupObserver<DataType = any> extends Observer {
3132
group: Group<DataType>,
3233
config: CreateObserverConfigInterface = {}
3334
) {
34-
super(group.agileInstance(), { ...config, ...{ value: group._output } });
35+
super(
36+
group.agileInstance(),
37+
defineConfig(config, { value: group._output })
38+
);
3539
this.group = () => group;
3640
this.nextGroupOutput = copy(group._output);
3741
}
@@ -67,7 +71,7 @@ export class GroupObserver<DataType = any> extends Observer {
6771
config: GroupIngestConfigInterface = {}
6872
): void {
6973
const group = this.group();
70-
config = {
74+
config = defineConfig(config, {
7175
perform: true,
7276
background: false,
7377
sideEffects: {
@@ -76,8 +80,7 @@ export class GroupObserver<DataType = any> extends Observer {
7680
},
7781
force: false,
7882
maxTriesToUpdate: 3,
79-
...config,
80-
};
83+
});
8184

8285
// Force overwriting the Group value if it is a placeholder.
8386
// After assigning a value to the Group, the Group is supposed to be no placeholder anymore.

0 commit comments

Comments
 (0)