@manyducks.co/dolla 0.76.0 → 0.77.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/notes/views.md CHANGED
@@ -1,4 +1,4 @@
1
- ```jsx
1
+ ```tsx
2
2
  import { View, Store, $, $$ } from "@manyducks.co/dolla";
3
3
 
4
4
  const SomeView = View("SomeView")
@@ -20,3 +20,176 @@ const SomeStore = Store("SomeStore").build((ctx) => {
20
20
  };
21
21
  });
22
22
  ```
23
+
24
+ Thoughts on reintegrating core APIs instead of keeping them as modular stores. In the case of things like the router, they really are core pieces masquerading as modular stores.
25
+
26
+ ```tsx
27
+ import { App } from "@manyducks.co/dolla";
28
+
29
+ const app = new App();
30
+
31
+ // All routes are defined using a config object.
32
+ app.route({
33
+ path: "/",
34
+ view: RootView,
35
+ routes: [
36
+ { path: "/example", view: ExampleView },
37
+ { path: "/notes", view: NotesView },
38
+ ],
39
+ });
40
+ app.route({ path: "*", redirect: "/example" });
41
+
42
+ function SomeView(props, ctx) {
43
+ // Route info and routing are exposed on ctx.route
44
+ ctx.route.go("/some-route", { preserveQuery: true, replace: false });
45
+ ctx.route.back();
46
+ ctx.route.forward();
47
+ ctx.route.$$query;
48
+ ctx.route.$params;
49
+ ctx.route.$path;
50
+ ctx.route.$pattern;
51
+ }
52
+ ```
53
+
54
+ HTTP is also integrated:
55
+
56
+ ```tsx
57
+ function SomeView(props, ctx) {
58
+ ctx.http.get("/some-route");
59
+ ctx.http.post("/some-route", { body: { data: 123 } });
60
+ // ... and the rest of the methods
61
+ }
62
+ ```
63
+
64
+ Language support is also integrated:
65
+
66
+ ```tsx
67
+ const app = new App();
68
+
69
+ app.language({ name: "en", path: "/locale/en.json" });
70
+ app.language({ name: "ja", path: "/locale/ja.json" });
71
+ app.setLanguage("en" /* or localStorage.getItem("appLanguage") or something */);
72
+
73
+ function SomeView(props, ctx) {
74
+ ctx.language.$current;
75
+ ctx.language.set("ja");
76
+ ctx.language.translate$("some.key");
77
+
78
+ // I would probably use it like this:
79
+ const { translate$ } = ctx.language;
80
+ translate$("some.key");
81
+ }
82
+ ```
83
+
84
+ ## Stores vs Context variables
85
+
86
+ Now, these are going away as stores. But what about stores? I'd like to replace stores with context variables, like this:
87
+
88
+ ```tsx
89
+ function ParentView(props, ctx) {
90
+ // Variables can be set in this context...
91
+
92
+ ctx.set("fixedValue", 1);
93
+
94
+ const $$writable = $$(2);
95
+ ctx.set("$$writableValue", $$writable);
96
+
97
+ return <ChildView />;
98
+ }
99
+
100
+ function ChildView(props, ctx) {
101
+ // ... and accessed in a child context.
102
+
103
+ const fixed = ctx.get<number>("fixedValue"); // 1
104
+ const $$writable = ctx.get<Writable<number>>("$$writableValue"); // Writable(2)
105
+
106
+ // Overriding values will not change parent variables. This value will take effect for this context and any child context.
107
+ ctx.set("fixedValue", 2);
108
+
109
+ return <span>{$$writable}</span>;
110
+ }
111
+
112
+ // Now stores can be written and used in this way:
113
+
114
+ function ExampleStore(ctx: ViewContext) {
115
+ ctx.beforeConnect(() => {
116
+ // Takes whatever arguments, in this case the ViewContext itself so it can attach lifecycle methods.
117
+ });
118
+
119
+ return {
120
+ whatever: 1,
121
+ };
122
+ }
123
+
124
+ function ExampleView(props, ctx) {
125
+ ctx.set("example", ExampleStore(ctx));
126
+
127
+ // ...
128
+ }
129
+
130
+ function ChildView(props, ctx) {
131
+ const example = ctx.get("example");
132
+
133
+ ctx.log(example.whatever); // prints: 1
134
+ }
135
+ ```
136
+
137
+ Or as a class-based thing:
138
+
139
+ ```tsx
140
+ import { View, Store } from "@manyducks.co/dolla";
141
+
142
+ // Stores are basically an observable map with computed properties.
143
+ const example = new Store({
144
+ computed: {
145
+ uppercased: (values) => values.key.toUpperCase(),
146
+ },
147
+ });
148
+
149
+ // Set one or more properties at a time.
150
+ example.set({ key: "value" });
151
+
152
+ // Get the current value of any property by name.
153
+ example.get("uppercased"); // "VALUE"
154
+
155
+ // Can subscribe to specific entries.
156
+ const sub = example.subscribe("key", (value) => {
157
+ // Do something when value changes.
158
+ });
159
+ sub.unsubscribe();
160
+ sub.current; // get current value of entry
161
+
162
+ // Get a two-way binding to a particular entry.
163
+ const bound = example.bind("key");
164
+ const boundSub = bound.subscribe((value) => {
165
+ // Do something when value changes.
166
+ });
167
+ boundSub.current; // get current value
168
+ bound.get();
169
+ bound.set(newValue);
170
+
171
+ // Now Views have a state that works in a very similar way.
172
+
173
+ interface ExampleViewState {
174
+ whatever: number;
175
+ }
176
+
177
+ interface ExampleViewProps {
178
+ // Bound values can be passed as props to child views.
179
+ something: Bound<string>;
180
+ }
181
+
182
+ class ExampleView extends View<ExampleViewState, ExampleViewProps> {
183
+ create() {
184
+ this.state.set({ whatever: 5 });
185
+
186
+ const whatever = this.state.bind("whatever");
187
+
188
+ this.state.subscribe("whatever", (value) => {
189
+ // This will be automatically cleaned up when the view is disconnected.
190
+ });
191
+
192
+ this.props.something.get(); // get the value of the bound prop.
193
+ }
194
+ }
195
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@manyducks.co/dolla",
3
- "version": "0.76.0",
3
+ "version": "0.77.0",
4
4
  "description": "Front-end components, routing and state management.",
5
5
  "main": "lib/index.js",
6
6
  "types": "./index.d.ts",