Skip to content

Commit f0495c5

Browse files
committed
v0.0.1
0 parents  commit f0495c5

File tree

7 files changed

+1094
-0
lines changed

7 files changed

+1094
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
3+
yarn-error.log

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 c-py
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# One Way Data Binding Library .MJS
2+
3+
## 😎 Description 🙏
4+
5+
Maps a javascript objects to arbitrary create, update and delete functions.
6+
7+
Can be used to sync stateful or stateless components to some other provider of data.
8+
9+
## 🚀 Installation 😱
10+
11+
```bash
12+
yarn add one-way-data-binding-library.mjs
13+
```
14+
15+
## 💯 Basic Usage 👆
16+
17+
```js
18+
import oneWayDataBindingLibraryJs from "one-way-data-binding-library.mjs";
19+
20+
const bar = () => ({
21+
create: (relative, absolute) => console.log("Create", relative, absolute),
22+
update: (relative, absolute) => console.log("Update", relative, absolute),
23+
delete: (absolute) => console.log("Delete", absolute),
24+
});
25+
26+
const run = oneWayDataBindingLibraryJs({ "foo.bar": bar });
27+
28+
// Create
29+
run(() => ({ foo: { bar: { hello: "world" } } }));
30+
31+
// Update
32+
run((state) => {
33+
state.foo.bar.hello = "moon";
34+
});
35+
36+
// Delete
37+
run((state) => ({}));
38+
```
39+
40+
## 💪 Additional Usage 😂
41+
42+
### Multiple Paths
43+
44+
```js
45+
const example = () => ({
46+
create: (relative, absolute) => console.log("Create", relative, absolute),
47+
update: (relative, absolute) => console.log("Update", relative, absolute),
48+
delete: (absolute) => console.log("Delete", absolute),
49+
});
50+
51+
const run = oneWayDataBindingLibraryJs({
52+
"foo.bar": example,
53+
"foo.baz": example,
54+
});
55+
56+
run(() => ({
57+
foo: {
58+
bar: {},
59+
baz: {},
60+
},
61+
}));
62+
```
63+
64+
### Wildcards
65+
66+
```js
67+
const example = () => ({
68+
create: (relative, absolute) => console.log("Create", relative, absolute),
69+
update: (relative, absolute) => console.log("Update", relative, absolute),
70+
delete: (absolute) => console.log("Delete", absolute),
71+
});
72+
73+
const run = oneWayDataBindingLibraryJs({
74+
"foo.*": example,
75+
});
76+
77+
run(() => ({
78+
foo: {
79+
bar: {},
80+
baz: {},
81+
},
82+
}));
83+
```
84+
85+
## 👀 Help & Documentation 🎉
86+
87+
### Path Matching
88+
89+
JSON Path matching utilises Object Scan: https://github.com/blackflux/object-scan
90+
91+
### State Updates
92+
93+
State updates are Immer patch expressions: https://github.com/immerjs/immer

one-way-data-binding-library.mjs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import scan from "object-scan";
2+
import { produce } from "immer";
3+
4+
export default (bindings) => {
5+
let state = {};
6+
let bound = {};
7+
8+
const processor = (update) => {
9+
state = produce(state, update);
10+
11+
const nextBound = {};
12+
13+
scan(Object.keys(bindings), {
14+
joined: true,
15+
rtn: ["key", "value", "matchedBy"],
16+
})(state).forEach(([key, data, matchedBy]) => {
17+
matchedBy.forEach((match) => {
18+
// No binding exists for this key; bind and call create method
19+
if (!(key in bound)) {
20+
nextBound[key] = { methods: bindings[match](), data };
21+
if (nextBound[key].methods.create) {
22+
nextBound[key].methods.create(data, state);
23+
}
24+
}
25+
// Binding exists and data reference has changed; call update method
26+
else if (bound[key].methods.update && data !== bound[key].data) {
27+
nextBound[key] = { methods: bound[key].methods, data };
28+
nextBound[key].methods.update(data, state);
29+
}
30+
});
31+
});
32+
33+
Object.keys(bound).forEach((key) => {
34+
if (!(key in nextBound) || nextBound[key] === undefined) {
35+
bound[key].methods.delete?.();
36+
}
37+
});
38+
39+
bound = nextBound;
40+
41+
return processor;
42+
};
43+
44+
return processor;
45+
};

0 commit comments

Comments
 (0)