You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Oct 1, 2022. It is now read-only.
Copy file name to clipboardExpand all lines: docs/v4/docs/controllers.md
+10-14Lines changed: 10 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,17 +22,15 @@ core.accounts.myAction();
22
22
23
23
The first parameter of the Controller function is `ControllerConfig`
24
24
25
-
```js
26
-
constApp=newPulse();
27
-
28
-
constconfig= {
29
-
collection:App.Collection()(),
30
-
state: {
31
-
MY_STATE:App.State(),
32
-
MY_COMPUTED_STATE:App.Computed(() =>true)
33
-
}
25
+
```ts
26
+
import {collection, state} from'@pulsejs/core'
27
+
28
+
const accounts = {
29
+
collection: collection(),
30
+
MY_STATE: state(),
31
+
MY_COMPUTED_STATE: state(() =>true)
34
32
};
35
-
exportconstaccounts=App.Controller(config);
33
+
exportconst accounts;
36
34
```
37
35
38
36
## Config Structure
@@ -60,7 +58,7 @@ For TypeScript users, the inferred types of the object you pass in will be prese
60
58
61
59
In some cases you will prefer to use more than the default Controller categories, you might want to spread actions to the root of the controller instance so they can be access like the following.
62
60
63
-
```js
61
+
```ts
64
62
accounts.myAction();
65
63
```
66
64
@@ -83,15 +81,13 @@ This is how a controller folder should be organized.
The order of imports above is important, state/collections must be imported first to also allow them to be imported into `actions.ts` without creating a cyclic import. Sometimes this can cause `import * as ...` to return an empty object at runtime, following this structure will avoid that.
setCore(core);// register your core and initialize computed states
34
34
35
-
exporttypeICore=typeofcore;
35
+
exportdefaultcore;
36
36
```
37
37
38
38
Imports for `accounts` and `authentication` were ommited for this example.
39
39
40
-
The Pulse instance is created first as `App`, followed by an object that forms the root of the core object, in this case we're passing in two arbitrary Controllers.
41
-
42
-
Now we register the core with `App.Core()` which snapshots the core object. It can now be accessed anywhere with the very same function, without any parameters. (See [Usage]())
43
-
44
-
> _In practice the initilization of App should be in a seperate file (eg: `app.ts`) as it must occur before the imports that require the `App` instance and TSLint doesn't like code above imports._
40
+
An object forms the root of the core object, in this case we're passing in two arbitrary Controllers.
45
41
46
-
See [Creating your core]() for the more detailed structure.
47
-
48
-
::: tip Why export the type?
49
-
We're unable to directly import the core into controllers, as it would create cyclic dependencies which can cause horrible compile issues, especially at scale. This is why we use `App.Core()` to get the core inside controllers, but it still wouldn't be type safe.
50
-
51
-
However, TypeScript types are immune to this paradox and can time travel. :crystal_ball: Once you declare them, they are able to be refrenced in code before and after declaration. This means we can import just the type of the finalized core into our individual controllers.
52
-
53
-
Now when making changes to one Controller you'll see full intelisense in the other—regardless of the order the controllers are initialized.
54
-
:::
55
-
56
-
## Usage
57
-
58
-
The core can be accessed from both outside and within itself, which means the syntax is slightly different for each. To demonstrate, we'll import and access a Controller named `accounts`.
59
-
60
-
> From **within** the core (this could be any file within)
61
-
62
-
```ts
63
-
import { App } from'./app'; // instance
64
-
import { ICore } from'./core'; // type from the future
65
-
66
-
const core =App.Core<ICore>();
67
-
```
68
-
69
-
This method ensures this Controller can access other Controllers, even ones that might not be initialized yet. We import our time-traveling type `ICore` and assign it to the Core functions' generic.
70
-
71
-
> From **outside** the core
72
-
73
-
```js
74
-
importcorefrom'./core';
75
-
76
-
core.accounts;
77
-
```
78
-
79
-
It's safe to use the default import here as we know everything has been initialized, this would be the easiest way to access the core in your UI components.
42
+
Now we register the core with `setCore()` which snapshots the core object.
80
43
81
44
### Caveats
82
45
83
-
#### 1) Destructuing imports
84
-
85
-
In an ideal world we'd be able to do this:
86
-
87
-
```ts
88
-
const { accounts } =App.Core<ICore>();
89
-
```
90
-
91
-
This would not work because at import-level accounts has not been defined yet, as assembly of the core happens last.
92
-
93
-
However if you import **without** destructuing, the constant you assign will be a direct reference to the core object within the App instance. So at runtime it will work.
94
-
95
-
```ts
96
-
const core =App.Core<ICore>();
97
-
```
98
-
99
-
#### 2) Using the core to supply initial state
46
+
#### 1) Using the core to supply initial state
100
47
101
48
A way to remember this rule, is to only use `core.` notation inside functions that are not **immediately called**. Such as Computed functions and actions.
By this point your core should look something like this:
74
+
Atthispoint, yourcoreshouldlooksomethinglikethis:
140
75
::: vue
141
-
├── **core**
76
+
├── **/core**
142
77
│ ├── **index.ts**
143
-
│ ├── `app.ts`
144
78
:::
145
79
146
80
>Leaveindex.tsemptyfornow.
147
81
148
82
### NewDirectory: `controllers`
149
83
150
-
Create a folder for your conrollers. Pulse advocates splitting up your core into modules using the [Controller]() class to containerize the module. However this step is optional, you're free to structure your core however you'd like.
84
+
Createafolderforyourconrollers. Pulseadvocatessplittingupyourcoreintomodulesusinganobject; however, thisstepisoptional. You're free to structure your core however you'dlike.
151
85
152
-
> See [Controller]() documentation for more detail
Pulse is flexible, so you are free to do you own thing, but you must ensure that at the very least instance creation comes first, core construction comes last.
0 commit comments