schemind 0.2.0 → 0.2.1

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.
Files changed (2) hide show
  1. package/README.md +137 -2
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -61,7 +61,142 @@ npm install schemind
61
61
  ```
62
62
 
63
63
  ## Usage
64
- TODO
64
+ ### Defining a schema
65
+ ```typescript
66
+ import { buildSchema, withIndex as i } from "schemind";
67
+
68
+ const personSchema = buildSchema({
69
+ id: i(0)<number>(),
70
+ fullName: i(1)<string>(),
71
+ email: i(2)<string>(),
72
+ birthDate: i(3)<Date>(),
73
+ address: i(4)({
74
+ street: i(0)<string>(),
75
+ city: i(1)<string>(),
76
+ zipcode: i(2)<string>(),
77
+ geo: i(3)({
78
+ lat: i(0)<number>(),
79
+ lng: i(1)<number>()
80
+ })
81
+ }),
82
+ website: i(5)<string>()
83
+ });
84
+ ```
85
+ Every field needs to have its index in the message specified using `withIndex`.
86
+ Note that this also goes for nested objects, such as `address`.
87
+
88
+ * If you accidentally pass the same index twice, or you forget to call `withIndex` on any nested object, `buildSchema` will throw an `InvalidSchemaError`.
89
+ * If you forget to call `buildSchema` on your object, you'll get a type error when trying to use your schema.
90
+
91
+
92
+ ### Reading from a message
93
+ Say you have an incoming message (from network/storage/whatever) like this:
94
+ ```typescript
95
+ const incomingMessage = JSON.parse(`
96
+ [
97
+ 1,
98
+ "John Doe",
99
+ "johndoe@example.com",
100
+ "1973-01-22",
101
+ [
102
+ "123 Main Street",
103
+ "Anytown",
104
+ "12345-6789",
105
+ [
106
+ 42.1234,
107
+ -71.2345
108
+ ]
109
+ ],
110
+ "www.johndoe.com"
111
+ ]`);
112
+ ```
113
+
114
+ There are 2 ways to read this message:
115
+ #### • `toPlainObject`
116
+ This is the more convenient option.
117
+ ```typescript
118
+ import { toPlainObject } from "schemind";
119
+
120
+ const messageAsObject = toPlainObject(incomingMessage, personSchema);
121
+ // ^ this has the following type:
122
+ // {
123
+ // id: number,
124
+ // fullName: string,
125
+ // email: string,
126
+ // birthDate: Date,
127
+ // address: {
128
+ // street: string,
129
+ // city: string,
130
+ // zipcode: string,
131
+ // geo: {
132
+ // lat: number,
133
+ // lng: number
134
+ // }
135
+ // },
136
+ // website: string
137
+ // }
138
+ ```
139
+ #### • `get`
140
+ This is the more performant option – it doesn't allocate on the heap.
141
+ ```typescript
142
+ const fullName = get(incomingMessage, personSchema.fullName);
143
+ // ^ this is of type string
144
+
145
+ const latitude = get(incomingMessage, personSchema.address.geo.lat);
146
+ // ^ this is of type number
147
+ ```
148
+ Alternatively, you can use the method "get". It works in the exact same way.
149
+ ```typescript
150
+ const fullName = personSchema.fullName.get(incomingMessage);
151
+ const latitude = personSchema.address.geo.lat.get(incomingMessage);
152
+ ```
153
+
154
+ ### Writing
155
+ There are 2 ways to write a message.
156
+
157
+ #### • `toIndexedKeysMessage`
158
+ ```typescript
159
+ import { toIndexedKeysMessage } from "schemind";
160
+
161
+ const objectToSerialize = {
162
+ id: 1,
163
+ fullName: "John Doe",
164
+ email: "johndoe@example.com",
165
+ birthDate: new Date(),
166
+ address: {
167
+ street: "123 Main Street",
168
+ city: "Anytown",
169
+ zipcode: "12345-6789",
170
+ geo: {
171
+ lat: 42.1234,
172
+ lng: -71.2345
173
+ }
174
+ },
175
+ website: "www.johndoe.com"
176
+ };
177
+
178
+ const message = toIndexedKeysMessage(objectToSerialize, personSchema);
179
+ // ^ this is an array that's the same as the "incomingMessage" in the previous section
180
+
181
+ // JSON.stringify(message) or whatever
182
+ ```
183
+
184
+ #### • `set`
185
+
186
+ ```typescript
187
+ import { set } from "schemind";
188
+
189
+ const newMessage: unknown[] = [];
190
+ set(newMessage, personSchema.fullName, "John Doe");
191
+ set(newMessage, personSchema.address.geo.lat, 42.1234);
192
+ // ^ this is type-checked
193
+ // etc
194
+ ```
195
+ Alternatively, you can use the method "set". It works in the exact same way.
196
+ ```typescript
197
+ personSchema.fullName.set(newMessage, "John Doe");
198
+ personSchema.address.geo.lat.set(newMessage, 42.1234);
199
+ ```
65
200
 
66
201
  ## FAQ
67
202
  ### Shouldn't this be an extension of a serializer?
@@ -72,7 +207,7 @@ Possibly. But if you're already using JSON / MessagePack / CBOR etc. in your app
72
207
 
73
208
  Additionally, in some languages (backend or frontend) there's a MessagePack or JSON implementation that's faster, or allocates less memory, than protobuf.
74
209
 
75
- ### Why is `get` so inconvenient?
210
+ ### Why would I use `get` if it's inconvenient?
76
211
  The `get` function prioritizes performance over convenience. The main goal here is to avoid any heap allocations (beyond what your deserializer allocates). I use *schemind* in performance-critical scenarios, where avoiding GC pauses is crucial.
77
212
  Use the `toPlainObject` function instead, if you don't mind some extra allocations.
78
213
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "schemind",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Read and write to messages serialized as arrays (indexed keys) by defining a schema, \nenabling smaller message size when using protocols such as msgpack or JSON.",
5
5
  "keywords": [
6
6
  "serialization",