primate 0.6.3 → 0.6.4

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/README.md CHANGED
@@ -7,9 +7,77 @@ expressive code.
7
7
  ## Installing
8
8
 
9
9
  ```
10
- npm install primate
10
+ $ npm install primate
11
11
  ```
12
12
 
13
+ ## Quick start
14
+
15
+ Lay out your app
16
+
17
+ ```
18
+ $ mkdir -p primate-app/{routes,components,ssl} && cd primate-app
19
+ ```
20
+
21
+ Create a route for `/`
22
+
23
+ ```
24
+ // routes/site.js
25
+
26
+ import {router, html} from "primate";
27
+
28
+ router.get("/", () => html`<site-index date=${new Date()} />`);
29
+ ```
30
+
31
+ Create component for your route
32
+
33
+ ```
34
+ // components/site-index.html
35
+
36
+ Today's date is <span data-value="date"></span>.
37
+ ```
38
+
39
+ Generate SSL key/certificate
40
+
41
+ ```
42
+ openssl req -x509 -out ssl/default.crt -keyout ssl/default.key -newkey rsa:2048 -nodes -sha256 -batch
43
+ ```
44
+
45
+ Add an entry file
46
+
47
+ ```
48
+ // app.js
49
+
50
+ import {app} from "primate";
51
+ app.run();
52
+ ```
53
+
54
+ Create and start script and enable ES modules
55
+
56
+ ```
57
+ // package.json
58
+
59
+ {
60
+ "scripts": {
61
+ "start": "node --experimental-json-modules app.js"
62
+ },
63
+ "type": "module"
64
+ }
65
+ ```
66
+
67
+ Install Primate
68
+
69
+ ```
70
+ $ npm install primate
71
+ ```
72
+
73
+ Run app
74
+
75
+ ```
76
+ $ npm start
77
+ ```
78
+
79
+ Visit `https://localhost:9999`
80
+
13
81
  ## Highlights
14
82
 
15
83
  * Flexible HTTP routing, returning HTML, JSON or a custom handler
@@ -17,15 +85,15 @@ npm install primate
17
85
  * Built-in support for sessions with secure cookies
18
86
  * Input verification using data domains
19
87
  * Many different data store modules: In-Memory (built-in),
20
- [File][primate-store-file], [JSON][primate-store-json],
21
- [MongoDB][primate-store-mongodb]
88
+ [File][primate-file-store], [JSON][primate-json-store],
89
+ [MongoDB][primate-mongodb-store]
22
90
  * Easy modelling of`1:1`, `1:n` and `n:m` relationships
23
91
  * Minimally opinionated with sane, overrideable defaults
24
92
  * No dependencies
25
93
 
26
- ## Getting started
94
+ ## Resources
27
95
 
28
- See the [getting started][getting-started] guide.
96
+ * [Getting started guide]
29
97
 
30
98
  ## License
31
99
 
@@ -34,6 +102,6 @@ BSD-3-Clause
34
102
  [getting-started]: https://primatejs.com/getting-started
35
103
  [source-code]: https://github.com/primatejs/primate
36
104
  [issues]: https://github.com/primatejs/primate/issues
37
- [primate-store-file]: https://npmjs.com/primate-store-file
38
- [primate-store-json]: https://npmjs.com/primate-store-json
39
- [primate-store-mongodb]: https://npmjs.com/primate-store-mongodb
105
+ [primate-file-store]: https://npmjs.com/primate-file-store
106
+ [primate-json-store]: https://npmjs.com/primate-json-store
107
+ [primate-mongodb-store]: https://npmjs.com/primate-mongodb-store
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "primate",
3
- "version": "0.6.3",
3
+ "version": "0.6.4",
4
4
  "author": "Primate core team <core@primatejs.com>",
5
5
  "homepage": "https://primatejs.com",
6
6
  "bugs": "https://github.com/primatejs/primate/issues",
@@ -44,6 +44,6 @@ const last = -1;
44
44
  const eager = async (strings, ...keys) =>
45
45
  (await Promise.all(strings.slice(0, last).map(async (string, i) =>
46
46
  strings[i] + await keys[i]
47
- ))).join("") + strings[strings.length+last];
47
+ ))).join("") + strings.at(last);
48
48
 
49
49
  export {eager};
@@ -74,12 +74,19 @@ export default class Parser {
74
74
  }
75
75
  }
76
76
 
77
+ try_create_text_node() {
78
+ if (this.buffer.length > 0) {
79
+ const child = new Node(this.node, "span");
80
+ child.text = this.buffer;
81
+ this.buffer = "";
82
+ }
83
+ }
84
+
77
85
  // currently outside of a tag
78
86
  process_not_reading_tag() {
79
87
  // encountered '<'
80
88
  if (this.current === "<") {
81
- this.node.text = this.buffer;
82
- this.buffer = "";
89
+ this.try_create_text_node();
83
90
  // mark as inside tag
84
91
  this.reading_tag = true;
85
92
  if (this.next === "/") {
@@ -111,6 +118,8 @@ export default class Parser {
111
118
  if (this.balance !== 0) {
112
119
  throw Error(`unbalanced DOM tree: ${this.balance}`);
113
120
  }
121
+ // anything left at the end could be potentially a text node
122
+ this.try_create_text_node();
114
123
  return this.tree;
115
124
  }
116
125
 
@@ -1,4 +1,5 @@
1
1
  import {constructible, nullish} from "./attributes.js";
2
+ import map_entries from "./map_entries.js";
2
3
 
3
4
  const errored = error => {
4
5
  if (typeof error === "function") {
@@ -14,6 +15,9 @@ const assert = (predicate, error) => Boolean(predicate) || errored(error);
14
15
  const is = {
15
16
  "array": value => assert(Array.isArray(value), "must be array"),
16
17
  "string": value => assert(typeof value === "string", "must be string"),
18
+ "object": value => assert(typeof value === "object" && value !== null,
19
+ "must be object"),
20
+ "function": value => assert(typeof value === "function", "must be function"),
17
21
  "defined": (value, error) => assert(value !== undefined, error),
18
22
  "undefined": value => assert(value === undefined, "must be undefined"),
19
23
  "constructible": (value, error) => assert(constructible(value), error),
@@ -24,9 +28,10 @@ const is = {
24
28
  };
25
29
  const {defined} = is;
26
30
 
27
- const maybe = Object.keys(is).reduce((aggregator, property) => {
28
- aggregator[property] = value => nullish(value) || is[property](value);
29
- return aggregator;
30
- }, {});
31
+ // too early to use map_entries here, as it relies on invariants
32
+ const maybe = Object.fromEntries(Object.entries(is).map(([key, value]) =>
33
+ [key, (...args) => nullish(args[0]) || value(...args)]));
31
34
 
32
- export {assert, defined, is, maybe};
35
+ const invariant = predicate => predicate();
36
+
37
+ export {assert, defined, is, maybe, invariant};
@@ -0,0 +1,6 @@
1
+ import {is, invariant} from "./invariants.js";
2
+
3
+ export default (object = {}, mapper = (...args) => args) =>
4
+ invariant(() => is.object(object) && is.function(mapper))
5
+ && Object.fromEntries(Object.entries(object).map(([key, value]) =>
6
+ mapper(key, value)));
@@ -1,10 +1,8 @@
1
- export default (payload = {}) => Object.keys(payload)
2
- .map(key => ({key, "value": payload[key].toString().trim()}))
3
- .map(datum => {
4
- datum.value = datum.value === "" ? undefined : datum.value;
5
- return datum;
6
- })
7
- .reduce((data, {key, value}) => {
8
- data[key] = value;
9
- return data;
10
- }, {});
1
+ import {is} from "./invariants.js";
2
+ import map_entries from "./map_entries.js";
3
+
4
+ export default (dirty = {}) => is.object(dirty)
5
+ && map_entries(dirty, (key, value) => {
6
+ const trimmed = value.toString().trim();
7
+ return [key, trimmed === "" ? undefined : trimmed];
8
+ });