Comparing version 1.1.7 to 1.1.8
@@ -0,1 +1,5 @@ | ||
# 1.1.8 | ||
* Fixed #21 wrong export of `setDefaultModelSchema` export, by @vonovak | ||
# 1.1.7 | ||
@@ -2,0 +6,0 @@ |
{ | ||
"name": "serializr", | ||
"version": "1.1.7", | ||
"version": "1.1.8", | ||
"description": "Serialize and deserialize complex object graphs to JSON", | ||
@@ -54,2 +54,2 @@ "main": "serializr.js", | ||
} | ||
} | ||
} |
358
README.md
@@ -35,3 +35,3 @@ # Serializr | ||
From CDN: <https://npmcdn.com/serializr> which declares the global `serializr` object. | ||
From CDN: <https://unpkg.com/serializr> which declares the global `serializr` object. | ||
@@ -42,3 +42,3 @@ # Quick example: | ||
import { | ||
createModelSchema, primitive, reference, list, object, identifier, serialize, deserialize | ||
createModelSchema, primitive, reference, list, object, identifier, serialize, deserialize | ||
} from "serializr"; | ||
@@ -48,3 +48,3 @@ | ||
class User { | ||
uuid = Math.random(); | ||
uuid = Math.floor(Math.random()*10000); | ||
displayName = "John Doe"; | ||
@@ -54,8 +54,21 @@ } | ||
class Message { | ||
message = "Test"; | ||
author = null; | ||
message = "Test"; | ||
author = null; | ||
comments = []; | ||
} | ||
findUserById(uuid, callback) { | ||
function fetchUserSomewhere(uuid) { | ||
// Lets pretend to actually fetch a user; but not. | ||
// In a real app this might be a database query | ||
const user = new User(); | ||
user.uuid = uuid; | ||
user.displayName = `John Doe ${uuid}`; | ||
return user; | ||
} | ||
function findUserById(uuid, callback, context) { | ||
// This is a lookup function | ||
// identifier is the identifier being resolved | ||
// callback is a node style calblack function to be invoked with the found object (as second arg) or an error (first arg) | ||
// context is an object detailing the execution context of the serializer now | ||
callback(null, fetchUserSomewhere(uuid)) | ||
@@ -66,23 +79,27 @@ } | ||
createModelSchema(Message, { | ||
message: primitive(), | ||
author: reference(User, findUserById), | ||
message : primitive(), | ||
author : reference(User, findUserById), | ||
comments: list(object(Message)) | ||
}) | ||
}); | ||
createModelSchema(User, { | ||
uuid: identifier(), | ||
uuid : identifier(), | ||
displayName: primitive() | ||
}) | ||
}); | ||
// can now deserialize and serialize! | ||
const message = deserialize(Message, { | ||
message: "Hello world", | ||
author: 17, | ||
comments: [{ | ||
message: "Welcome!", | ||
author: 23 | ||
}] | ||
}) | ||
message : "Hello world", | ||
author : 17, | ||
comments: [ | ||
{ | ||
message: "Welcome!", | ||
author : 23 | ||
} | ||
] | ||
}); | ||
const json = serialize(message) | ||
const json = serialize(message); | ||
console.dir(message, {colors: true, depth: 10}); | ||
``` | ||
@@ -96,6 +113,7 @@ | ||
import { | ||
createModelSchema, primitive, reference, list, object, identifier, serialize, deserialize, | ||
createModelSchema, primitive, reference, list, object, identifier, serialize, deserialize, getDefaultModelSchema, | ||
serializable | ||
} from "serializr"; | ||
class User { | ||
@@ -113,10 +131,51 @@ @serializable(identifier()) | ||
@serializable(reference(User, findUserById)) | ||
@serializable(object(User)) | ||
author = null; | ||
// Self referencing decorators work in Babel 5.x and Typescript. See below for more. | ||
@serializable(list(object(Message))) | ||
comments = []; | ||
} | ||
// You can now deserialize and serialize! | ||
const message = deserialize(Message, { | ||
message : "Hello world", | ||
author : {uuid: 1, displayName: "Alice"}, | ||
comments: [ | ||
{ | ||
message: "Welcome!", | ||
author : {uuid: 1, displayName: "Bob"} | ||
} | ||
] | ||
}); | ||
console.dir(message, {colors: true, depth: 10}); | ||
// We can call serialize without the first argument here | ||
//because the schema can be inferred from the decorated classes | ||
const json = serialize(message); | ||
``` | ||
**Decorator: Caveats** | ||
Babel 6.x does not allow decorators to self-reference during their creation, so the above code would not work for the Message class. Instead write: | ||
```javascript | ||
class Message { | ||
@serializable | ||
message = "Test"; | ||
@serializable(object(User)) | ||
author = null; | ||
comments = []; | ||
constructor(){ | ||
getDefaultModelSchema(Message).props["comments"] = list(object(Message)); | ||
} | ||
} | ||
``` | ||
## Enabling decorators (optional) | ||
@@ -128,7 +187,15 @@ | ||
**Babel:** | ||
**Babel 5.x** | ||
```json | ||
{ | ||
"stage": 1 | ||
} | ||
``` | ||
**Babel 6.x:** | ||
Install support for decorators: `npm i --save-dev babel-plugin-transform-decorators-legacy`. And enable it in your `.babelrc` file: | ||
```javascript | ||
```json | ||
{ | ||
@@ -152,3 +219,3 @@ "presets": ["es2015", "stage-1"], | ||
A model schema simple looks like this: | ||
A simple model schema looks like this: | ||
@@ -166,8 +233,8 @@ ```javascript | ||
The `factory` tells how to construct new instances during deserialization. | ||
The optional `extends` property denotes that this model schema inherits it's props from another model schema. | ||
The props section describe how individual model properties are to be (de)serialized. Their names match the model field names. | ||
The optional `extends` property denotes that this model schema inherits its props from another model schema. | ||
The props section describes how individual model properties are to be (de)serialized. Their names match the model field names. | ||
The combination `fieldname: true` is simply a shorthand for `fieldname: primitive()` | ||
For convenience, model schemas can be stored on the constructor function of a class. | ||
This allows you to pass in a class reference everywhere where a model schema is required. | ||
This allows you to pass in a class reference wherever a model schema is required. | ||
See the examples below. | ||
@@ -177,8 +244,8 @@ | ||
Prop schemas contain the strategy on how individual fields should be serialized. | ||
PropSchemas contain the strategy on how individual fields should be serialized. | ||
It denotes whether a field is a primitive, list, whether it needs to be aliased, refers to other model objects etc. | ||
Propschemas are composable. See the API section below for the details, but these are the built in property schemas: | ||
PropSchemas are composable. See the API section below for the details, but these are the built-in property schemas: | ||
- `primitive()`: Serialize a field as primitive value | ||
- `identifier()`: Serialize a field as primitive value, use it as identifier when serializing references (see `ref`) | ||
- `identifier()`: Serialize a field as primitive value, use it as identifier when serializing references (see `reference`) | ||
- `date()`: Serializes dates (as epoch number) | ||
@@ -195,3 +262,3 @@ - `alias(name, propSchema)`: Serializes a field under a different name | ||
```javascript | ||
```typings | ||
{ | ||
@@ -203,7 +270,7 @@ serializer: (sourcePropertyValue: any) => jsonValue, | ||
For inspiration, take a look at the source code of the existing ones on how they work, it is pretty straight forward. | ||
For inspiration, take a look at the source code of the existing ones on how they work, it is pretty straightforward. | ||
## Deserialization context | ||
The context object is an advanced feature and can be used to obtain additional context related information about the deserialization process. | ||
The context object is an advanced feature and can be used to obtain additional context-related information about the deserialization process. | ||
`context` is available as: | ||
@@ -224,8 +291,52 @@ | ||
## ModelSchema | ||
[serializr.js:126-133](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L126-L133 "Source code on GitHub") | ||
JSDOC type defintions for usage w/o typescript. | ||
**Parameters** | ||
- `value` **Any** | ||
- `targetClass` | ||
- `get` **([Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function) \| [undefined](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined))** | ||
- `set` **([Function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function) \| [undefined](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined))** | ||
- `configurable` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** | ||
- `enumerable` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** | ||
- `sourcePropertyValue` **Any** | ||
- `jsonValue` **Any** | ||
- `callback` **cpsCallback** | ||
- `context` **Context** | ||
- `writeable` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** | ||
- `id` **Any** | ||
- `target` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** | ||
- `context` **Context** | ||
- `result` **Any** | ||
- `error` **Any** | ||
- `id` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** | ||
- `callback` **cpsCallback** | ||
- `factory` | ||
- `props` | ||
- `currentPropertyValue` **Any** | ||
**Properties** | ||
- `serializer` **serializerFunction** | ||
- `deserializer` **deserializerFunction** | ||
- `identifier` **[boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** | ||
Returns **Any** any - serialized object | ||
Returns **Any** void | ||
Returns **Any** void | ||
Returns **Any** void | ||
## createSimpleSchema | ||
[serializr.js:79-86](https://github.com/mobxjs/serializr/blob/f971d8764b9e93b388723443519a726d809dc921/serializr.js#L79-L86 "Source code on GitHub") | ||
[serializr.js:126-133](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L126-L133 "Source code on GitHub") | ||
Creates a model schema that (de)serializes from / to plain javascript objects. | ||
It's factory method is: `() => ({})` | ||
Its factory method is: `() => ({})` | ||
@@ -242,3 +353,3 @@ **Parameters** | ||
done: true | ||
}; | ||
}); | ||
@@ -253,11 +364,11 @@ var json = serialize(todoSchema, { title: "Test", done: false }) | ||
[serializr.js:112-130](https://github.com/mobxjs/serializr/blob/f971d8764b9e93b388723443519a726d809dc921/serializr.js#L112-L130 "Source code on GitHub") | ||
[serializr.js:159-177](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L159-L177 "Source code on GitHub") | ||
Creates a model schema that (de)serializes an object created by a constructor function (class). | ||
The created model schema is associated by the targeted type as default model schema, see setDefaultModelSchema. | ||
It's factory method is `() => new clazz()` (unless overriden, see third arg). | ||
Its factory method is `() => new clazz()` (unless overriden, see third arg). | ||
**Parameters** | ||
- `clazz` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** clazz or constructor function | ||
- `clazz` **([constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor) | class)** class or constructor function | ||
- `props` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** property mapping | ||
@@ -287,3 +398,3 @@ - `factory` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** optional custom factory. Receives context as first arg | ||
[serializr.js:161-171](https://github.com/mobxjs/serializr/blob/f971d8764b9e93b388723443519a726d809dc921/serializr.js#L161-L171 "Source code on GitHub") | ||
[serializr.js:208-218](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L208-L218 "Source code on GitHub") | ||
@@ -293,3 +404,3 @@ Decorator that defines a new property mapping on the default model schema for the class | ||
If using typescript, the decorator can also be used on fields declared as constructor arguments (using the `private` / `protected` / `public` keywords). | ||
When using typescript, the decorator can also be used on fields declared as constructor arguments (using the `private` / `protected` / `public` keywords). | ||
The default factory will then invoke the constructor with the correct arguments as well. | ||
@@ -313,3 +424,3 @@ | ||
[serializr.js:239-248](https://github.com/mobxjs/serializr/blob/f971d8764b9e93b388723443519a726d809dc921/serializr.js#L239-L248 "Source code on GitHub") | ||
[serializr.js:286-295](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L286-L295 "Source code on GitHub") | ||
@@ -320,14 +431,13 @@ Returns the standard model schema associated with a class / constructor function | ||
- `clazz` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** class or constructor function | ||
- `thing` | ||
- `thing` **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** | ||
Returns **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** model schema | ||
Returns **[ModelSchema](#modelschema)** model schema | ||
## setDefaultModelSchema | ||
[serializr.js:261-264](https://github.com/mobxjs/serializr/blob/f971d8764b9e93b388723443519a726d809dc921/serializr.js#L261-L264 "Source code on GitHub") | ||
[serializr.js:309-312](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L309-L312 "Source code on GitHub") | ||
Sets the default model schema for class / constructor function. | ||
Everywhere where a model schema is required as argument, this class / constructor function | ||
can be passed in as well (for example when using `child` or `ref`. | ||
can be passed in as well (for example when using `object` or `ref`. | ||
@@ -339,10 +449,10 @@ When passing an instance of this class to `serialize`, it is not required to pass the model schema | ||
- `clazz` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** class or constructor function | ||
- `modelSchema` | ||
- `clazz` **([constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor) | class)** class or constructor function | ||
- `modelSchema` **[ModelSchema](#modelschema)** a model schema | ||
Returns **[object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** model schema | ||
Returns **[ModelSchema](#modelschema)** model schema | ||
## serialize | ||
[serializr.js:316-334](https://github.com/mobxjs/serializr/blob/f971d8764b9e93b388723443519a726d809dc921/serializr.js#L316-L334 "Source code on GitHub") | ||
[serializr.js:364-382](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L364-L382 "Source code on GitHub") | ||
@@ -362,5 +472,5 @@ Serializes an object (graph) into json using the provided model schema. | ||
[serializr.js:388-406](https://github.com/mobxjs/serializr/blob/f971d8764b9e93b388723443519a726d809dc921/serializr.js#L388-L406 "Source code on GitHub") | ||
[serializr.js:436-454](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L436-L454 "Source code on GitHub") | ||
Deserializes an json structor into an object graph. | ||
Deserializes a json structor into an object graph. | ||
This process might be asynchronous (for example if there are references with an asynchronous | ||
@@ -372,11 +482,13 @@ lookup function). The function returns an object (or array of objects), but the returned object | ||
- `schema` | ||
- `schema` **([object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) \| [array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array))** to use for deserialization | ||
- `json` **[json](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON)** data to deserialize | ||
- `callback` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** node style callback that is invoked once the deserializaiton has finished. | ||
First argument is the optional error, second argument is the deserialized object (same as the return value) | ||
- `customArgs` **any** custom arguments that are available as `context.args` during the deserialization process. This can be used as dependency injection mechanism to pass in, for example, stores. | ||
- `customArgs` **Any** custom arguments that are available as `context.args` during the deserialization process. This can be used as dependency injection mechanism to pass in, for example, stores. | ||
Returns **([object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object) \| [array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array))** deserialized object, possibly incomplete. | ||
## update | ||
[serializr.js:572-591](https://github.com/mobxjs/serializr/blob/f971d8764b9e93b388723443519a726d809dc921/serializr.js#L572-L591 "Source code on GitHub") | ||
[serializr.js:620-639](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L620-L639 "Source code on GitHub") | ||
@@ -393,7 +505,7 @@ Similar to deserialize, but updates an existing object instance. | ||
- `callback` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** the callback to invoke once deserialization has completed. | ||
- `customArgs` **any** custom arguments that are available as `context.args` during the deserialization process. This can be used as dependency injection mechanism to pass in, for example, stores. | ||
- `customArgs` **Any** custom arguments that are available as `context.args` during the deserialization process. This can be used as dependency injection mechanism to pass in, for example, stores. | ||
## primitive | ||
[serializr.js:613-625](https://github.com/mobxjs/serializr/blob/f971d8764b9e93b388723443519a726d809dc921/serializr.js#L613-L625 "Source code on GitHub") | ||
[serializr.js:661-673](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L661-L673 "Source code on GitHub") | ||
@@ -413,18 +525,19 @@ Indicates that this field contains a primitive value (or Date) which should be serialized literally to json. | ||
Returns **PropSchema** | ||
Returns **[ModelSchema](#modelschema)** | ||
## identifier | ||
[serializr.js:660-674](https://github.com/mobxjs/serializr/blob/f971d8764b9e93b388723443519a726d809dc921/serializr.js#L660-L674 "Source code on GitHub") | ||
[serializr.js:712-726](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L712-L726 "Source code on GitHub") | ||
Similar to primitive, but this field will be marked as the identifier for the given Model type. | ||
This is used by for example `ref()` to serialize the reference | ||
This is used by for example `reference()` to serialize the reference | ||
Identifier accepts an optional `registerFn` with the signature: | ||
`(id, target, context) => void` | ||
that can be used to register this object in some store. note that not all fields of this object might have been deserialized yet | ||
that can be used to register this object in some store. note that not all fields of this object might | ||
have been deserialized yet. | ||
**Parameters** | ||
- `registerFn` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** optional function to register this object during creation. | ||
- `registerFn` **RegisterFunction** optional function to register this object during creation. | ||
@@ -459,3 +572,3 @@ **Examples** | ||
[serializr.js:685-700](https://github.com/mobxjs/serializr/blob/f971d8764b9e93b388723443519a726d809dc921/serializr.js#L685-L700 "Source code on GitHub") | ||
[serializr.js:737-752](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L737-L752 "Source code on GitHub") | ||
@@ -466,3 +579,3 @@ Similar to primitive, serializes instances of Date objects | ||
[serializr.js:719-730](https://github.com/mobxjs/serializr/blob/f971d8764b9e93b388723443519a726d809dc921/serializr.js#L719-L730 "Source code on GitHub") | ||
[serializr.js:771-782](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L771-L782 "Source code on GitHub") | ||
@@ -474,4 +587,3 @@ Alias indicates that this model property should be named differently in the generated json. | ||
- `alias` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** name of the json field to be used for this property | ||
- `name` | ||
- `name` **[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)** name of the json field to be used for this property | ||
- `propSchema` **PropSchema** propSchema to (de)serialize the contents of this field | ||
@@ -494,3 +606,3 @@ | ||
[serializr.js:749-758](https://github.com/mobxjs/serializr/blob/f971d8764b9e93b388723443519a726d809dc921/serializr.js#L749-L758 "Source code on GitHub") | ||
[serializr.js:801-810](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L801-L810 "Source code on GitHub") | ||
@@ -517,10 +629,10 @@ Can be used to create simple custom propSchema. | ||
Returns **propSchema** | ||
Returns **PropSchema** | ||
## object | ||
[serializr.js:785-803](https://github.com/mobxjs/serializr/blob/f971d8764b9e93b388723443519a726d809dc921/serializr.js#L785-L803 "Source code on GitHub") | ||
[serializr.js:841-859](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L841-L859 "Source code on GitHub") | ||
`object` indicates that this property contains an object that needs to be (de)serialized | ||
using it's own model schema. | ||
using its own model schema. | ||
@@ -531,3 +643,3 @@ N.B. mind issues with circular dependencies when importing model schema's from other files! The module resolve algorithm might expose classes before `createModelSchema` is executed for the target class. | ||
- `modelSchema` **modelSchema** to be used to (de)serialize the child | ||
- `modelSchema` **[ModelSchema](#modelschema)** to be used to (de)serialize the object | ||
@@ -537,9 +649,12 @@ **Examples** | ||
```javascript | ||
class SubTask{} | ||
class Todo{} | ||
createModelSchema(SubTask, { | ||
title: true | ||
}) | ||
}); | ||
createModelSchema(Todo, { | ||
title: true | ||
title: true, | ||
subTask: object(SubTask) | ||
}) | ||
}); | ||
@@ -551,3 +666,3 @@ const todo = deserialize(Todo, { | ||
} | ||
}) | ||
}); | ||
``` | ||
@@ -559,5 +674,5 @@ | ||
[serializr.js:857-890](https://github.com/mobxjs/serializr/blob/f971d8764b9e93b388723443519a726d809dc921/serializr.js#L857-L890 "Source code on GitHub") | ||
[serializr.js:918-951](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L918-L951 "Source code on GitHub") | ||
`reference` can be used to (de)serialize references that points to other models. | ||
`reference` can be used to (de)serialize references that point to other models. | ||
@@ -568,3 +683,3 @@ The first parameter should be either a ModelSchema that has an `identifier()` property (see identifier) | ||
The second parameter is a lookup function that is invoked during deserialization to resolve an identifier to | ||
an object. It's signature should be as follows: | ||
an object. Its signature should be as follows: | ||
@@ -579,3 +694,3 @@ `lookupFunction(identifier, callback, context)` where: | ||
N.B. mind issues with circular dependencies when importing model schema's from other files! The module resolve algorithm might expose classes before `createModelSchema` is executed for the target class. | ||
N.B. mind issues with circular dependencies when importing model schemas from other files! The module resolve algorithm might expose classes before `createModelSchema` is executed for the target class. | ||
@@ -585,4 +700,3 @@ **Parameters** | ||
- `target` : ModelSchema or string | ||
- `lookup` **[function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function)** function | ||
- `lookupFn` | ||
- `lookupFn` **RefLookupFunction** function | ||
@@ -592,2 +706,5 @@ **Examples** | ||
```javascript | ||
class User{} | ||
class Post{} | ||
createModelSchema(User, { | ||
@@ -599,3 +716,3 @@ uuid: identifier(), | ||
createModelSchema(Post, { | ||
author: reference(User, findUserById) | ||
author: reference(User, findUserById), | ||
message: primitive() | ||
@@ -628,3 +745,3 @@ }) | ||
[serializr.js:922-943](https://github.com/mobxjs/serializr/blob/f971d8764b9e93b388723443519a726d809dc921/serializr.js#L922-L943 "Source code on GitHub") | ||
[serializr.js:988-1009](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L988-L1009 "Source code on GitHub") | ||
@@ -641,2 +758,6 @@ List indicates that this property contains a list of things. | ||
```javascript | ||
class SubTask{} | ||
class Task{} | ||
class Todo{} | ||
createModelSchema(SubTask, { | ||
@@ -646,4 +767,4 @@ title: true | ||
createModelSchema(Todo, { | ||
title: true | ||
subTask: list(child(SubTask)) | ||
title: true, | ||
subTask: list(object(SubTask)) | ||
}) | ||
@@ -663,3 +784,3 @@ | ||
[serializr.js:957-1006](https://github.com/mobxjs/serializr/blob/f971d8764b9e93b388723443519a726d809dc921/serializr.js#L957-L1006 "Source code on GitHub") | ||
[serializr.js:1023-1072](https://github.com/mobxjs/serializr/blob/d2222d56a87478568563367066d20324033600a1/serializr.js#L1023-L1072 "Source code on GitHub") | ||
@@ -672,3 +793,3 @@ Similar to list, but map represents a string keyed dynamic collection. | ||
- `propSchema` **any** | ||
- `propSchema` **Any** | ||
@@ -812,21 +933,37 @@ # Recipes and examples | ||
```javascript | ||
// Box.js: | ||
// models.js: | ||
import {observable, computed} from 'mobx'; | ||
import {randomUuid} from '../utils'; | ||
import {serializable, identifier} from 'serializr'; | ||
export default class Box { | ||
@serializable(identifier()) id; | ||
@observable @serializable name = 'Box' + this.id; | ||
function randomId() { | ||
return Math.floor(Math.random()*100000); | ||
} | ||
export class Box { | ||
@serializable(identifier()) id = randomId(); | ||
@serializable @observable x = 0; | ||
@serializable @observable y = 0; | ||
@computed get width() { | ||
return this.name.length * 15; | ||
@serializable @observable location = 0; | ||
constructor(location, x, y){ | ||
this.location = location; | ||
this.x = x; | ||
this.y = y; | ||
} | ||
@serializable @computed get area() { | ||
return this.x * this.y; | ||
} | ||
} | ||
// Store.js: | ||
export class Arrow{ | ||
@serializable(identifier()) id = randomId(); | ||
@serializable(reference(Box)) from; | ||
@serializable(reference(Box)) to; | ||
} | ||
// store.js: | ||
import {observable, transaction} from 'mobx'; | ||
import {createSimpleSchema, ref, identifier, child, list, serialize, deserialize, update} from 'serializr'; | ||
import Box from './box'; | ||
import {createSimpleSchema, identifier, list, serialize, deserialize, update} from 'serializr'; | ||
import {Box, Arrow} from './models'; | ||
@@ -840,18 +977,11 @@ // The store that holds our domain: boxes and arrows | ||
// Model of an arrow | ||
const arrowModel = createSimpleSchema({ | ||
id: identifier(), | ||
from: reference(Box) | ||
to: reference(Box) | ||
}) | ||
// Model of the store itself | ||
const storeModel = createSimpleSchema({ | ||
boxes: list(object(Box)), | ||
arrows: list(object(arrowModel)), | ||
// context.target is the current store being deserialized | ||
selection: ref(Box) | ||
}) | ||
arrows: list(object(Arrow)), | ||
selection: reference(Box) | ||
}); | ||
// example data | ||
// Example Data | ||
// You can push data in as a class | ||
store.boxes.push( | ||
@@ -862,4 +992,5 @@ new Box('Rotterdam', 100, 100), | ||
// Or it can be an raw javascript object with the right properties | ||
store.arrows.push({ | ||
id: randomUuid(), | ||
id: randomId(), | ||
from: store.boxes[0], | ||
@@ -874,3 +1005,3 @@ to: store.boxes[1] | ||
function deserializeState = (store, json) { | ||
function deserializeState(store, json) { | ||
transaction(() => { | ||
@@ -880,2 +1011,5 @@ update(storeModel, store, json); | ||
} | ||
// Print ... out for debugging | ||
console.dir(serializeState(store), {depth: 10, colors: true}); | ||
``` | ||
@@ -882,0 +1016,0 @@ |
@@ -60,2 +60,3 @@ // TODO: put this in the source files, and extract it, to preserve comments | ||
export type RefLookupFunction = (id: string, callback: (err: any, result: any) => void) => void; | ||
export type RegisterFunction = (id: any, object: any, context: Context) => void; | ||
@@ -62,0 +63,0 @@ export function ref(modelschema: ClazzOrModelSchema<any>, lookupFn?: RefLookupFunction): PropSchema; |
142
serializr.js
@@ -62,6 +62,53 @@ (function(g) { | ||
*/ | ||
/** | ||
* JSDOC type defintions for usage w/o typescript. | ||
* @typedef {object} PropSchema | ||
* @property {serializerFunction} serializer | ||
* @property {deserializerFunction} deserializer | ||
* @property {boolean} identifier | ||
* | ||
* @typedef {object} PropertyDescriptor | ||
* @param {*} value | ||
* @param {boolean} writeable | ||
* @param {Function|undefined} get | ||
* @param {Function|undefined} set | ||
* @param {boolean} configurable | ||
* @param {boolean} enumerable | ||
* | ||
* @callback serializerFunction | ||
* @param {*} sourcePropertyValue | ||
* @returns any - serialized object | ||
* | ||
* | ||
* @callback deserializerFunction | ||
* @param {*} jsonValue | ||
* @param {cpsCallback} callback | ||
* @param {Context} context | ||
* @param {*} currentPropertyValue | ||
* @returns void | ||
* | ||
* @callback RegisterFunction | ||
* @param {*} id | ||
* @param {object} target | ||
* @param {Context} context | ||
* | ||
* @callback cpsCallback | ||
* @param {*} result | ||
* @param {*} error | ||
* @returns void | ||
* | ||
* @callback RefLookupFunction | ||
* @param {string} id | ||
* @param {cpsCallback} callback | ||
* @returns void | ||
* | ||
* @typedef {object} ModelSchema | ||
* @param factory | ||
* @param props | ||
* @param targetClass | ||
*/ | ||
/** | ||
* Creates a model schema that (de)serializes from / to plain javascript objects. | ||
* It's factory method is: `() => ({})` | ||
* Its factory method is: `() => ({})` | ||
* | ||
@@ -72,3 +119,3 @@ * @example | ||
* done: true | ||
* }; | ||
* }); | ||
* | ||
@@ -93,3 +140,3 @@ * var json = serialize(todoSchema, { title: "Test", done: false }) | ||
* The created model schema is associated by the targeted type as default model schema, see setDefaultModelSchema. | ||
* It's factory method is `() => new clazz()` (unless overriden, see third arg). | ||
* Its factory method is `() => new clazz()` (unless overriden, see third arg). | ||
* | ||
@@ -110,3 +157,3 @@ * @example | ||
* | ||
* @param {function} clazz clazz or constructor function | ||
* @param {constructor|class} clazz class or constructor function | ||
* @param {object} props property mapping | ||
@@ -140,3 +187,3 @@ * @param {function} factory optional custom factory. Receives context as first arg | ||
* | ||
* If using typescript, the decorator can also be used on fields declared as constructor arguments (using the `private` / `protected` / `public` keywords). | ||
* When using typescript, the decorator can also be used on fields declared as constructor arguments (using the `private` / `protected` / `public` keywords). | ||
* The default factory will then invoke the constructor with the correct arguments as well. | ||
@@ -241,4 +288,4 @@ * | ||
* | ||
* @param {function} clazz class or constructor function | ||
* @returns {object} model schema | ||
* @param {object} thing | ||
* @returns {ModelSchema} model schema | ||
*/ | ||
@@ -259,3 +306,3 @@ function getDefaultModelSchema(thing) { | ||
* Everywhere where a model schema is required as argument, this class / constructor function | ||
* can be passed in as well (for example when using `child` or `ref`. | ||
* can be passed in as well (for example when using `object` or `ref`. | ||
* | ||
@@ -265,4 +312,5 @@ * When passing an instance of this class to `serialize`, it is not required to pass the model schema | ||
* | ||
* @param {function} clazz class or constructor function | ||
* @returns {object} model schema | ||
* @param {constructor|class} clazz class or constructor function | ||
* @param {ModelSchema} modelSchema - a model schema | ||
* @returns {ModelSchema} model schema | ||
*/ | ||
@@ -292,3 +340,3 @@ function setDefaultModelSchema(clazz, modelSchema) { | ||
invariant(isModelSchema(modelSchema)) | ||
// optimizatoin: cache this lookup | ||
// optimization: cache this lookup | ||
while (modelSchema) { | ||
@@ -385,3 +433,3 @@ for (var propName in modelSchema.props) | ||
/** | ||
* Deserializes an json structor into an object graph. | ||
* Deserializes a json structor into an object graph. | ||
* This process might be asynchronous (for example if there are references with an asynchronous | ||
@@ -391,8 +439,8 @@ * lookup function). The function returns an object (or array of objects), but the returned object | ||
* | ||
* @param {object or array} modelschema to use for deserialization | ||
* @param {object|array} schema to use for deserialization | ||
* @param {json} json data to deserialize | ||
* @param {function} callback node style callback that is invoked once the deserializaiton has finished. | ||
* First argument is the optional error, second argument is the deserialized object (same as the return value) | ||
* @param {any} customArgs custom arguments that are available as `context.args` during the deserialization process. This can be used as dependency injection mechanism to pass in, for example, stores. | ||
* @returns {object or array} deserialized object, possibly incomplete. | ||
* @param {*} customArgs custom arguments that are available as `context.args` during the deserialization process. This can be used as dependency injection mechanism to pass in, for example, stores. | ||
* @returns {object|array} deserialized object, possibly incomplete. | ||
*/ | ||
@@ -581,3 +629,3 @@ function deserialize(schema, json, callback, customArgs) { | ||
* @param {function} callback the callback to invoke once deserialization has completed. | ||
* @param {any} customArgs custom arguments that are available as `context.args` during the deserialization process. This can be used as dependency injection mechanism to pass in, for example, stores. | ||
* @param {*} customArgs custom arguments that are available as `context.args` during the deserialization process. This can be used as dependency injection mechanism to pass in, for example, stores. | ||
*/ | ||
@@ -623,3 +671,3 @@ function update(modelSchema, target, json, callback, customArgs) { | ||
* | ||
* @returns {PropSchema} | ||
* @returns {ModelSchema} | ||
*/ | ||
@@ -641,8 +689,11 @@ function primitive() { | ||
/** | ||
* | ||
* | ||
* Similar to primitive, but this field will be marked as the identifier for the given Model type. | ||
* This is used by for example `ref()` to serialize the reference | ||
* This is used by for example `reference()` to serialize the reference | ||
* | ||
* Identifier accepts an optional `registerFn` with the signature: | ||
* `(id, target, context) => void` | ||
* that can be used to register this object in some store. note that not all fields of this object might have been deserialized yet | ||
* that can be used to register this object in some store. note that not all fields of this object might | ||
* have been deserialized yet. | ||
* | ||
@@ -670,4 +721,5 @@ * @example | ||
* | ||
* @param {function} registerFn optional function to register this object during creation. | ||
* | ||
* @param {RegisterFunction} registerFn optional function to register this object during creation. | ||
* | ||
* @returns {PropSchema} | ||
@@ -730,3 +782,3 @@ */ | ||
* | ||
* @param {string} alias name of the json field to be used for this property | ||
* @param {string} name name of the json field to be used for this property | ||
* @param {PropSchema} propSchema propSchema to (de)serialize the contents of this field | ||
@@ -763,3 +815,3 @@ * @returns {PropSchema} | ||
* @param {function} deserializer function that takes a json value and turns it into a model value | ||
* @returns {propSchema} | ||
* @returns {PropSchema} | ||
*/ | ||
@@ -779,3 +831,3 @@ function custom(serializer, deserializer) { | ||
* `object` indicates that this property contains an object that needs to be (de)serialized | ||
* using it's own model schema. | ||
* using its own model schema. | ||
* | ||
@@ -785,9 +837,13 @@ * N.B. mind issues with circular dependencies when importing model schema's from other files! The module resolve algorithm might expose classes before `createModelSchema` is executed for the target class. | ||
* @example | ||
* | ||
* class SubTask{} | ||
* class Todo{} | ||
* | ||
* createModelSchema(SubTask, { | ||
* title: true | ||
* }) | ||
* }); | ||
* createModelSchema(Todo, { | ||
* title: true | ||
* title: true, | ||
* subTask: object(SubTask) | ||
* }) | ||
* }); | ||
* | ||
@@ -799,5 +855,5 @@ * const todo = deserialize(Todo, { | ||
* } | ||
* }) | ||
* }); | ||
* | ||
* @param {modelSchema} modelSchema to be used to (de)serialize the child | ||
* @param {ModelSchema} modelSchema to be used to (de)serialize the object | ||
* @returns {PropSchema} | ||
@@ -826,3 +882,3 @@ */ | ||
/** | ||
* `reference` can be used to (de)serialize references that points to other models. | ||
* `reference` can be used to (de)serialize references that point to other models. | ||
* | ||
@@ -833,3 +889,3 @@ * The first parameter should be either a ModelSchema that has an `identifier()` property (see identifier) | ||
* The second parameter is a lookup function that is invoked during deserialization to resolve an identifier to | ||
* an object. It's signature should be as follows: | ||
* an object. Its signature should be as follows: | ||
* | ||
@@ -843,5 +899,10 @@ * `lookupFunction(identifier, callback, context)` where: | ||
* | ||
* N.B. mind issues with circular dependencies when importing model schema's from other files! The module resolve algorithm might expose classes before `createModelSchema` is executed for the target class. | ||
* N.B. mind issues with circular dependencies when importing model schemas from other files! The module resolve algorithm might expose classes before `createModelSchema` is executed for the target class. | ||
* | ||
* @example | ||
* | ||
* | ||
* class User{} | ||
* class Post{} | ||
* | ||
* createModelSchema(User, { | ||
@@ -853,3 +914,3 @@ * uuid: identifier(), | ||
* createModelSchema(Post, { | ||
* author: reference(User, findUserById) | ||
* author: reference(User, findUserById), | ||
* message: primitive() | ||
@@ -878,3 +939,3 @@ * }) | ||
* @param target: ModelSchema or string | ||
* @param {function} lookup function | ||
* @param {RefLookupFunction} lookupFn function | ||
* @returns {PropSchema} | ||
@@ -928,2 +989,7 @@ */ | ||
* @example | ||
* | ||
* class SubTask{} | ||
* class Task{} | ||
* class Todo{} | ||
* | ||
* createModelSchema(SubTask, { | ||
@@ -933,4 +999,4 @@ * title: true | ||
* createModelSchema(Todo, { | ||
* title: true | ||
* subTask: list(child(SubTask)) | ||
* title: true, | ||
* subTask: list(object(SubTask)) | ||
* }) | ||
@@ -981,3 +1047,3 @@ * | ||
* | ||
* @param {any} propSchema | ||
* @param {*} propSchema | ||
* @returns | ||
@@ -1042,3 +1108,3 @@ */ | ||
createSimpleSchema: createSimpleSchema, | ||
setDefaultModelSchema: getDefaultModelSchema, | ||
setDefaultModelSchema: setDefaultModelSchema, | ||
getDefaultModelSchema: getDefaultModelSchema, | ||
@@ -1045,0 +1111,0 @@ serializable: serializable, |
/** serializr - (c) Michel Weststrate 2016 - MIT Licensed */ | ||
!function(e){"use strict";function r(){function e(e){if(e)throw new Error(e)}function r(e){var r=!1;return function(){return r?void t(!1,"callback was invoked twice"):(r=!0,e.apply(null,arguments))}}function t(e,r){if(!e)throw new Error("[serializr] "+(r||"Illegal State"))}function n(e,r,t){if(0===e.length)return void t(null,[]);var n=e.length,i=[],o=!1,a=function(e,r,a){r?o||(o=!0,t(r)):(i[e]=a,0===--n&&t(null,i))};e.forEach(function(e,t){r(e,a.bind(null,t))})}function i(e){return null===e||"object"!=typeof e&&"function"!=typeof e}function o(e){return{factory:function(){return{}},props:e}}function a(e,r,n){t(e!==Object,"one cannot simply put define a model schema for Object"),t("function"==typeof e,"expected constructor function");var i={targetClass:e,factory:n||function(){return new e},props:r};if(e.prototype.constructor!==Object){var o=l(e.prototype.constructor);o&&o.targetClass!==e&&(i.extends=o)}return f(e,i),i}function s(e,r,n){if(1===arguments.length){var i=e===!0?B:e;return t(d(i),"@serializable expects prop schema"),c.bind(null,i)}return c(E(),e,r,n)}function u(e){var r=e.toString().replace(U,""),t=r.slice(r.indexOf("(")+1,r.indexOf(")")).match($);return null===t&&(t=[]),t}function c(e,r,n,i){t(arguments.length>=2,"too few arguments. Please use @serializable as property decorator");var o;if(void 0===n&&"function"==typeof r&&r.prototype&&void 0!==i&&"number"==typeof i){t(d(e),"Constructor params must use alias(name)"),t(e.jsonname,"Constructor params must use alias(name)");var s=u(r);s.length>=i&&(n=s[i],e.paramNumber=i,i=void 0,r=r.prototype,o=function(e){function t(e){return r.constructor.apply(this,e)}t.prototype=r.constructor.prototype;for(var n=[],i=0;i<r.constructor.length;i++)Object.keys(e.modelSchema.props).forEach(function(r){var t=e.modelSchema.props[r];t.paramNumber===i&&(n[i]=e.json[t.jsonname])});return new t(n)})}t("string"==typeof n,"incorrect usage of @serializable decorator");var c=l(r);return c&&r.constructor.hasOwnProperty("serializeInfo")||(c=a(r.constructor,{},o)),c&&c.targetClass!==r.constructor&&(c=a(r.constructor,{},o)),c.props[n]=e,!i||i.get||i.set||(i.writable=!0),i}function l(e){return e?p(e)?e:p(e.serializeInfo)?e.serializeInfo:e.constructor&&e.constructor.serializeInfo?e.constructor.serializeInfo:void 0:null}function f(e,r){return t(p(r)),e.serializeInfo=r}function p(e){return e&&e.factory&&e.props}function d(e){return e&&e.serializer&&e.deserializer}function h(e){return"object"==typeof e&&!!e.jsonname}function m(e){return"object"==typeof e&&e.identifier===!0}function v(e){for(t(p(e));e;){for(var r in e.props)if("object"==typeof e.props[r]&&e.props[r].identifier===!0)return r;e=e.extends}return null}function g(e,r){for(;e;){if(e===r)return!0;e=e.extends}return!1}function y(e,r){t(1===arguments.length||2===arguments.length,"serialize expects one or 2 arguments");var n=1===arguments.length?e:r,i=1===arguments.length?null:e;if(Array.isArray(n)){if(0===n.length)return[];i||(i=l(n[0]))}else i||(i=l(n));return t(!!i,"Failed to find default schema for "+e),Array.isArray(n)?n.map(function(e){return b(i,e)}):b(i,n)}function b(e,r){t(e&&"object"==typeof e,"Expected schema"),t(r&&"object"==typeof r,"Expected object");var n;return n=e.extends?b(e.extends,r):{},Object.keys(e.props).forEach(function(i){var o=e.props[i];if("*"===i)return t(o===!0,"prop schema '*' can onle be used with 'true'"),void z(e,r,n);if(o===!0&&(o=B),o!==!1){var a=o.serializer(r[i]);n[o.jsonname||i]=a}}),n}function z(e,r,n){for(var o in r)if(r.hasOwnProperty(o)&&!(o in e.props)){var a=r[o];t(i(a),"encountered non primitive value while serializing '*' properties in property '"+o+"': "+a),n[o]=a}}function j(r,i,o,a){if(t(arguments.length>=2,"deserialize expects at least 2 arguments"),r=l(r),t(p(r),"first argument should be model schema"),Array.isArray(i)){var s=[];return n(i,function(e,t){var n=x(null,r,e,t,a);s.push(n)},o||e),s}return x(null,r,i,o,a)}function x(r,n,i,o,a){if(null===i||void 0===i)return void o(null,null);var s=new k(r,n,i,o,a),u=n.factory(s);t(!!u,"No object returned from factory"),s.target=u;var c=s.createCallback(e);return R(s,n,i,u),c(),u}function R(e,r,n,i){r.extends&&R(e,r.extends,n,i),Object.keys(r.props).forEach(function(o){var a=r.props[o];if("*"===o)return t(a===!0,"prop schema '*' can onle be used with 'true'"),void w(r,i,n);if(a===!0&&(a=B),a!==!1){var s=a.jsonname||o;s in n&&a.deserializer(n[s],e.rootContext.createCallback(function(e){i[o]=e}),e,i[o])}})}function C(e,r){for(var t in e.props)if("object"==typeof e.props[t]&&e.props[t].jsonname===r)return!0;return!1}function w(e,r,n){for(var o in n)if(!(o in e.props||C(e,o))){var a=n[o];t(i(a),"encountered non primitive value while deserializing '*' properties in property '"+o+"': "+a),r[o]=a}}function k(r,t,n,i,o){this.parentContext=r,this.isRoot=!r,this.pendingCallbacks=0,this.pendingRefsCount=0,this.onReadyCb=i||e,this.json=n,this.target=null,this.hasError=!1,this.modelSchema=t,this.isRoot?(this.rootContext=this,this.args=o,this.pendingRefs={},this.resolvedRefs={}):(this.rootContext=r.rootContext,this.args=r.args)}function S(r,n,i,o,a){var s=2===arguments.length||"function"==typeof arguments[2];s&&(n=arguments[0],r=l(n),i=arguments[1],o=arguments[2],a=arguments[3]),t(p(r),"update failed to determine schema"),t("object"==typeof n&&n&&!Array.isArray(n),"update needs an object");var u=new k(null,r,i,o,a);u.target=n;var c=u.createCallback(e);R(u,r,i,n),c()}function E(){return{serializer:function(e){return t(i(e),"this value is not primitive: "+e),e},deserializer:function(e,r){return i(e)?void r(null,e):void r("[serializr] this value is not primitive: "+e)}}}function O(e){return t(!e||"function"==typeof e,"First argument should be ommitted or function"),{identifier:!0,serializer:B.serializer,deserializer:function(r,t,n){B.deserializer(r,function(r,i){A(i,n.target,n),e&&e(i,n.target,n),t(r,i)})}}}function A(e,r,t){t.rootContext.resolve(t.modelSchema,e,t.target)}function I(){return{serializer:function(e){return null===e||void 0===e?e:(t(e instanceof Date,"Expected Date object"),e.getTime())},deserializer:function(e,r){return null===e||void 0===e?void r(null,e):void r(null,new Date(e))}}}function N(e,r){return t(e&&"string"==typeof e,"expected prop name as first argument"),r=r&&r!==!0?r:B,t(d(r),"expected prop schema as second argument"),t(!h(r),"provided prop is already aliased"),{jsonname:e,serializer:r.serializer,deserializer:r.deserializer,identifier:m(r)}}function D(e,r){return t("function"==typeof e,"first argument should be function"),t("function"==typeof r,"second argument should be function"),{serializer:e,deserializer:function(e,t){t(null,r(e))}}}function M(e){return t("object"==typeof e||"function"==typeof e,"No modelschema provided. If you are importing it from another file be aware of circular dependencies."),{serializer:function(r){return e=l(e),t(p(e),"expected modelSchema, got "+e),null===r||void 0===r?r:y(e,r)},deserializer:function(r,n,i){return e=l(e),t(p(e),"expected modelSchema, got "+e),null===r||void 0===r?void n(null,r):void x(i,e,r,n)}}}function P(e,r){function n(){if(o=!0,t("string"!=typeof e||r,"if the reference target is specified by attribute name, a lookup function is required"),t(!r||"function"==typeof r,"second argument should be a lookup function"),"string"==typeof e)i=e;else{var n=l(e);t(p(n),"expected model schema or string as first argument for 'ref', got "+n),r=r||F(n),i=v(n),t(!!i,"provided model schema doesn't define an identifier() property and cannot be used by 'ref'.")}}t(!!e,"No modelschema provided. If you are importing it from another file be aware of circular dependencies.");var i,o=!1;return{serializer:function(e){return o||n(),e?e[i]:null},deserializer:function(e,t,i){o||n(),null===e||void 0===e?t(null,e):r(e,t,i)}}}function F(e){return function(r,t,n){n.rootContext.await(e,r,t)}}function J(e){return e=e||B,t(d(e),"expected prop schema as second argument"),t(!h(e),"provided prop is aliased, please put aliases first"),{serializer:function(r){return t(r&&"length"in r&&"map"in r,"expected array (like) object"),r.map(e.serializer)},deserializer:function(r,t,i){return Array.isArray(r)?void n(r,function(r,t){return e.deserializer(r,t,i)},t):void t("[serializr] expected JSON array")}}}function q(e){return e&&"function"==typeof e.keys&&"function"==typeof e.clear}function T(e){return e=e||B,t(d(e),"expected prop schema as second argument"),t(!h(e),"provided prop is aliased, please put aliases first"),{serializer:function(r){t(r&&"object"==typeof r,"expected object or Map");var n=q(r),i={};if(n)r.forEach(function(r,t){i[t]=e.serializer(r)});else for(var o in r)i[o]=e.serializer(r[o]);return i},deserializer:function(r,t,n,i){if(!r||"object"!=typeof r)return void t("[serializr] expected JSON object");var o=Object.keys(r);J(e).deserializer(o.map(function(e){return r[e]}),function(e,r){if(e)return void t(e);var n,a=q(i);a?(i.clear(),n=i):n={};for(var s=0,u=o.length;s<u;s++)a?n.set(o[s],r[s]):n[o[s]]=r[s];t(null,n)},n)}}}var U=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,$=/([^\s,]+)/g;k.prototype.createCallback=function(e){return this.pendingCallbacks++,r(function(r,t){r?this.hasError||(this.hasError=!0,this.onReadyCb(r)):this.hasError||(e(t),--this.pendingCallbacks===this.pendingRefsCount&&(this.pendingRefsCount>0?this.onReadyCb(new Error('Unresolvable references in json: "'+Object.keys(this.pendingRefs).filter(function(e){return this.pendingRefs[e].length>0},this).join('", "')+'"')):this.onReadyCb(null,this.target)))}.bind(this))},k.prototype.await=function(e,r,n){if(t(this.isRoot),r in this.resolvedRefs){var i=this.resolvedRefs[r].filter(function(r){return g(r.modelSchema,e)})[0];if(i)return void n(null,i.value)}this.pendingRefsCount++,this.pendingRefs[r]||(this.pendingRefs[r]=[]),this.pendingRefs[r].push({modelSchema:e,uuid:r,callback:n})},k.prototype.resolve=function(e,r,n){if(t(this.isRoot),this.resolvedRefs[r]||(this.resolvedRefs[r]=[]),this.resolvedRefs[r].push({modelSchema:e,value:n}),r in this.pendingRefs)for(var i=this.pendingRefs[r].length-1;i>=0;i--){var o=this.pendingRefs[r][i];g(e,o.modelSchema)&&(this.pendingRefs[r].splice(i,1),this.pendingRefsCount--,o.callback(null,n))}};var B=E();return{createModelSchema:a,createSimpleSchema:o,setDefaultModelSchema:l,getDefaultModelSchema:l,serializable:s,serialize:y,deserialize:j,update:S,primitive:E,identifier:O,date:I,alias:N,list:J,map:T,object:M,child:M,reference:P,ref:P,custom:D}}"object"==typeof exports?module.exports=r():"function"==typeof define&&define.amd?define("serializr",[],r):e.serializr=r()}(function(){return this}()); | ||
!function(e){"use strict";function r(){function e(e){if(e)throw new Error(e)}function r(e){var r=!1;return function(){return r?void t(!1,"callback was invoked twice"):(r=!0,e.apply(null,arguments))}}function t(e,r){if(!e)throw new Error("[serializr] "+(r||"Illegal State"))}function n(e,r,t){if(0===e.length)return void t(null,[]);var n=e.length,i=[],o=!1,a=function(e,r,a){r?o||(o=!0,t(r)):(i[e]=a,0===--n&&t(null,i))};e.forEach(function(e,t){r(e,a.bind(null,t))})}function i(e){return null===e||"object"!=typeof e&&"function"!=typeof e}function o(e){return{factory:function(){return{}},props:e}}function a(e,r,n){t(e!==Object,"one cannot simply put define a model schema for Object"),t("function"==typeof e,"expected constructor function");var i={targetClass:e,factory:n||function(){return new e},props:r};if(e.prototype.constructor!==Object){var o=l(e.prototype.constructor);o&&o.targetClass!==e&&(i.extends=o)}return f(e,i),i}function s(e,r,n){if(1===arguments.length){var i=e===!0?B:e;return t(d(i),"@serializable expects prop schema"),c.bind(null,i)}return c(E(),e,r,n)}function u(e){var r=e.toString().replace(U,""),t=r.slice(r.indexOf("(")+1,r.indexOf(")")).match($);return null===t&&(t=[]),t}function c(e,r,n,i){t(arguments.length>=2,"too few arguments. Please use @serializable as property decorator");var o;if(void 0===n&&"function"==typeof r&&r.prototype&&void 0!==i&&"number"==typeof i){t(d(e),"Constructor params must use alias(name)"),t(e.jsonname,"Constructor params must use alias(name)");var s=u(r);s.length>=i&&(n=s[i],e.paramNumber=i,i=void 0,r=r.prototype,o=function(e){function t(e){return r.constructor.apply(this,e)}t.prototype=r.constructor.prototype;for(var n=[],i=0;i<r.constructor.length;i++)Object.keys(e.modelSchema.props).forEach(function(r){var t=e.modelSchema.props[r];t.paramNumber===i&&(n[i]=e.json[t.jsonname])});return new t(n)})}t("string"==typeof n,"incorrect usage of @serializable decorator");var c=l(r);return c&&r.constructor.hasOwnProperty("serializeInfo")||(c=a(r.constructor,{},o)),c&&c.targetClass!==r.constructor&&(c=a(r.constructor,{},o)),c.props[n]=e,!i||i.get||i.set||(i.writable=!0),i}function l(e){return e?p(e)?e:p(e.serializeInfo)?e.serializeInfo:e.constructor&&e.constructor.serializeInfo?e.constructor.serializeInfo:void 0:null}function f(e,r){return t(p(r)),e.serializeInfo=r}function p(e){return e&&e.factory&&e.props}function d(e){return e&&e.serializer&&e.deserializer}function h(e){return"object"==typeof e&&!!e.jsonname}function m(e){return"object"==typeof e&&e.identifier===!0}function v(e){for(t(p(e));e;){for(var r in e.props)if("object"==typeof e.props[r]&&e.props[r].identifier===!0)return r;e=e.extends}return null}function g(e,r){for(;e;){if(e===r)return!0;e=e.extends}return!1}function y(e,r){t(1===arguments.length||2===arguments.length,"serialize expects one or 2 arguments");var n=1===arguments.length?e:r,i=1===arguments.length?null:e;if(Array.isArray(n)){if(0===n.length)return[];i||(i=l(n[0]))}else i||(i=l(n));return t(!!i,"Failed to find default schema for "+e),Array.isArray(n)?n.map(function(e){return b(i,e)}):b(i,n)}function b(e,r){t(e&&"object"==typeof e,"Expected schema"),t(r&&"object"==typeof r,"Expected object");var n;return n=e.extends?b(e.extends,r):{},Object.keys(e.props).forEach(function(i){var o=e.props[i];if("*"===i)return t(o===!0,"prop schema '*' can onle be used with 'true'"),void z(e,r,n);if(o===!0&&(o=B),o!==!1){var a=o.serializer(r[i]);n[o.jsonname||i]=a}}),n}function z(e,r,n){for(var o in r)if(r.hasOwnProperty(o)&&!(o in e.props)){var a=r[o];t(i(a),"encountered non primitive value while serializing '*' properties in property '"+o+"': "+a),n[o]=a}}function j(r,i,o,a){if(t(arguments.length>=2,"deserialize expects at least 2 arguments"),r=l(r),t(p(r),"first argument should be model schema"),Array.isArray(i)){var s=[];return n(i,function(e,t){var n=x(null,r,e,t,a);s.push(n)},o||e),s}return x(null,r,i,o,a)}function x(r,n,i,o,a){if(null===i||void 0===i)return void o(null,null);var s=new k(r,n,i,o,a),u=n.factory(s);t(!!u,"No object returned from factory"),s.target=u;var c=s.createCallback(e);return R(s,n,i,u),c(),u}function R(e,r,n,i){r.extends&&R(e,r.extends,n,i),Object.keys(r.props).forEach(function(o){var a=r.props[o];if("*"===o)return t(a===!0,"prop schema '*' can onle be used with 'true'"),void w(r,i,n);if(a===!0&&(a=B),a!==!1){var s=a.jsonname||o;s in n&&a.deserializer(n[s],e.rootContext.createCallback(function(e){i[o]=e}),e,i[o])}})}function C(e,r){for(var t in e.props)if("object"==typeof e.props[t]&&e.props[t].jsonname===r)return!0;return!1}function w(e,r,n){for(var o in n)if(!(o in e.props||C(e,o))){var a=n[o];t(i(a),"encountered non primitive value while deserializing '*' properties in property '"+o+"': "+a),r[o]=a}}function k(r,t,n,i,o){this.parentContext=r,this.isRoot=!r,this.pendingCallbacks=0,this.pendingRefsCount=0,this.onReadyCb=i||e,this.json=n,this.target=null,this.hasError=!1,this.modelSchema=t,this.isRoot?(this.rootContext=this,this.args=o,this.pendingRefs={},this.resolvedRefs={}):(this.rootContext=r.rootContext,this.args=r.args)}function S(r,n,i,o,a){var s=2===arguments.length||"function"==typeof arguments[2];s&&(n=arguments[0],r=l(n),i=arguments[1],o=arguments[2],a=arguments[3]),t(p(r),"update failed to determine schema"),t("object"==typeof n&&n&&!Array.isArray(n),"update needs an object");var u=new k(null,r,i,o,a);u.target=n;var c=u.createCallback(e);R(u,r,i,n),c()}function E(){return{serializer:function(e){return t(i(e),"this value is not primitive: "+e),e},deserializer:function(e,r){return i(e)?void r(null,e):void r("[serializr] this value is not primitive: "+e)}}}function O(e){return t(!e||"function"==typeof e,"First argument should be ommitted or function"),{identifier:!0,serializer:B.serializer,deserializer:function(r,t,n){B.deserializer(r,function(r,i){A(i,n.target,n),e&&e(i,n.target,n),t(r,i)})}}}function A(e,r,t){t.rootContext.resolve(t.modelSchema,e,t.target)}function I(){return{serializer:function(e){return null===e||void 0===e?e:(t(e instanceof Date,"Expected Date object"),e.getTime())},deserializer:function(e,r){return null===e||void 0===e?void r(null,e):void r(null,new Date(e))}}}function N(e,r){return t(e&&"string"==typeof e,"expected prop name as first argument"),r=r&&r!==!0?r:B,t(d(r),"expected prop schema as second argument"),t(!h(r),"provided prop is already aliased"),{jsonname:e,serializer:r.serializer,deserializer:r.deserializer,identifier:m(r)}}function D(e,r){return t("function"==typeof e,"first argument should be function"),t("function"==typeof r,"second argument should be function"),{serializer:e,deserializer:function(e,t){t(null,r(e))}}}function M(e){return t("object"==typeof e||"function"==typeof e,"No modelschema provided. If you are importing it from another file be aware of circular dependencies."),{serializer:function(r){return e=l(e),t(p(e),"expected modelSchema, got "+e),null===r||void 0===r?r:y(e,r)},deserializer:function(r,n,i){return e=l(e),t(p(e),"expected modelSchema, got "+e),null===r||void 0===r?void n(null,r):void x(i,e,r,n)}}}function P(e,r){function n(){if(o=!0,t("string"!=typeof e||r,"if the reference target is specified by attribute name, a lookup function is required"),t(!r||"function"==typeof r,"second argument should be a lookup function"),"string"==typeof e)i=e;else{var n=l(e);t(p(n),"expected model schema or string as first argument for 'ref', got "+n),r=r||F(n),i=v(n),t(!!i,"provided model schema doesn't define an identifier() property and cannot be used by 'ref'.")}}t(!!e,"No modelschema provided. If you are importing it from another file be aware of circular dependencies.");var i,o=!1;return{serializer:function(e){return o||n(),e?e[i]:null},deserializer:function(e,t,i){o||n(),null===e||void 0===e?t(null,e):r(e,t,i)}}}function F(e){return function(r,t,n){n.rootContext.await(e,r,t)}}function J(e){return e=e||B,t(d(e),"expected prop schema as second argument"),t(!h(e),"provided prop is aliased, please put aliases first"),{serializer:function(r){return t(r&&"length"in r&&"map"in r,"expected array (like) object"),r.map(e.serializer)},deserializer:function(r,t,i){return Array.isArray(r)?void n(r,function(r,t){return e.deserializer(r,t,i)},t):void t("[serializr] expected JSON array")}}}function q(e){return e&&"function"==typeof e.keys&&"function"==typeof e.clear}function T(e){return e=e||B,t(d(e),"expected prop schema as second argument"),t(!h(e),"provided prop is aliased, please put aliases first"),{serializer:function(r){t(r&&"object"==typeof r,"expected object or Map");var n=q(r),i={};if(n)r.forEach(function(r,t){i[t]=e.serializer(r)});else for(var o in r)i[o]=e.serializer(r[o]);return i},deserializer:function(r,t,n,i){if(!r||"object"!=typeof r)return void t("[serializr] expected JSON object");var o=Object.keys(r);J(e).deserializer(o.map(function(e){return r[e]}),function(e,r){if(e)return void t(e);var n,a=q(i);a?(i.clear(),n=i):n={};for(var s=0,u=o.length;s<u;s++)a?n.set(o[s],r[s]):n[o[s]]=r[s];t(null,n)},n)}}}var U=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm,$=/([^\s,]+)/g;k.prototype.createCallback=function(e){return this.pendingCallbacks++,r(function(r,t){r?this.hasError||(this.hasError=!0,this.onReadyCb(r)):this.hasError||(e(t),--this.pendingCallbacks===this.pendingRefsCount&&(this.pendingRefsCount>0?this.onReadyCb(new Error('Unresolvable references in json: "'+Object.keys(this.pendingRefs).filter(function(e){return this.pendingRefs[e].length>0},this).join('", "')+'"')):this.onReadyCb(null,this.target)))}.bind(this))},k.prototype.await=function(e,r,n){if(t(this.isRoot),r in this.resolvedRefs){var i=this.resolvedRefs[r].filter(function(r){return g(r.modelSchema,e)})[0];if(i)return void n(null,i.value)}this.pendingRefsCount++,this.pendingRefs[r]||(this.pendingRefs[r]=[]),this.pendingRefs[r].push({modelSchema:e,uuid:r,callback:n})},k.prototype.resolve=function(e,r,n){if(t(this.isRoot),this.resolvedRefs[r]||(this.resolvedRefs[r]=[]),this.resolvedRefs[r].push({modelSchema:e,value:n}),r in this.pendingRefs)for(var i=this.pendingRefs[r].length-1;i>=0;i--){var o=this.pendingRefs[r][i];g(e,o.modelSchema)&&(this.pendingRefs[r].splice(i,1),this.pendingRefsCount--,o.callback(null,n))}};var B=E();return{createModelSchema:a,createSimpleSchema:o,setDefaultModelSchema:f,getDefaultModelSchema:l,serializable:s,serialize:y,deserialize:j,update:S,primitive:E,identifier:O,date:I,alias:N,list:J,map:T,object:M,child:M,reference:P,ref:P,custom:D}}"object"==typeof exports?module.exports=r():"function"==typeof define&&define.amd?define("serializr",[],r):e.serializr=r()}(function(){return this}()); | ||
//# sourceMappingURL=serializr.min.js.map |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
109913
1142
976