Comparing version
@@ -7,6 +7,22 @@ import { JSON } from ".."; | ||
@json | ||
class Vec3 { | ||
public x!: i32; | ||
public y!: i32; | ||
public z!: i32; | ||
class RepoOwner { | ||
public login!: string; | ||
public id!: i32; | ||
public node_id!: string; | ||
public avatar_url!: string; | ||
public gravatar_id!: string; | ||
public url!: string; | ||
public html_url!: string; | ||
public followers_url!: string; | ||
public following_url!: string; | ||
public gists_url!: string; | ||
public starred_url!: string; | ||
public subscriptions_url!: string; | ||
public organizations_url!: string; | ||
public repos_url!: string; | ||
public events_url!: string; | ||
public received_events_url!: string; | ||
public type!: string; | ||
public user_view_type!: string; | ||
public site_admin!: boolean; | ||
} | ||
@@ -16,107 +32,201 @@ | ||
@json | ||
class LargeJSON { | ||
class RepoLicense { | ||
public key!: string; | ||
public name!: string; | ||
public spdx_id!: string; | ||
public url!: string | null; | ||
public node_id!: string; | ||
} | ||
@json | ||
class Repo { | ||
public id!: i32; | ||
public node_id!: string; | ||
public name!: string; | ||
public age!: i32; | ||
public email!: string; | ||
public street!: string; | ||
public city!: string; | ||
public state!: string; | ||
public zip!: string; | ||
public tags!: string[]; | ||
public theme!: string; | ||
public notifications!: boolean; | ||
public language!: string; | ||
public movement!: Vec3[]; | ||
public full_name!: string; | ||
public private!: boolean; | ||
public owner: RepoOwner = new RepoOwner(); | ||
public html_url!: string; | ||
public description!: string | null; | ||
public fork!: boolean; | ||
public url!: string; | ||
public forks_url!: string; | ||
public keys_url!: string; | ||
public collaborators_url!: string; | ||
public teams_url!: string; | ||
public hooks_url!: string; | ||
public issue_events_url!: string; | ||
public events_url!: string; | ||
public assignees_url!: string; | ||
public branches_url!: string; | ||
public tags_url!: string; | ||
public blobs_url!: string; | ||
public git_tags_url!: string; | ||
public git_refs_url!: string; | ||
public trees_url!: string; | ||
public statuses_url!: string; | ||
public languages_url!: string; | ||
public stargazers_url!: string; | ||
public contributors_url!: string; | ||
public subscribers_url!: string; | ||
public subscription_url!: string; | ||
public commits_url!: string; | ||
public git_commits_url!: string; | ||
public comments_url!: string; | ||
public issue_comment_url!: string; | ||
public contents_url!: string; | ||
public compare_url!: string; | ||
public merges_url!: string; | ||
public archive_url!: string; | ||
public downloads_url!: string; | ||
public issues_url!: string; | ||
public pulls_url!: string; | ||
public milestones_url!: string; | ||
public notifications_url!: string; | ||
public labels_url!: string; | ||
public releases_url!: string; | ||
public deployments_url!: string; | ||
public created_at!: string; | ||
public updated_at!: string; | ||
public pushed_at!: string; | ||
public git_url!: string; | ||
public ssh_url!: string; | ||
public clone_url!: string; | ||
public svn_url!: string; | ||
public homepage!: string | null; | ||
public size!: i32; | ||
public stargazers_count!: i32; | ||
public watchers_count!: i32; | ||
public language!: string | null; | ||
public has_issues!: boolean; | ||
public has_projects!: boolean; | ||
public has_downloads!: boolean; | ||
public has_wiki!: boolean; | ||
public has_pages!: boolean; | ||
public has_discussions!: boolean; | ||
public forks_count!: i32; | ||
public mirror_url!: string | null; | ||
public archived!: boolean; | ||
public disabled!: boolean; | ||
public open_issues_count!: i32; | ||
public license!: RepoLicense | null; | ||
public allow_forking!: boolean; | ||
public is_template!: boolean; | ||
public web_commit_signoff_required!: boolean; | ||
public topics!: string[]; | ||
public visibility!: string; | ||
public forks!: i32; | ||
public open_issues!: i32; | ||
public watchers!: i32; | ||
public default_branch!: string; | ||
} | ||
const v1: LargeJSON = { | ||
id: 2, | ||
name: "Medium Object", | ||
age: 18, | ||
email: "me@jairus.dev", | ||
street: "I don't want to say my street", | ||
city: "I don't want to say this either", | ||
state: "It really depends", | ||
zip: "I forget what it is", | ||
tags: ["me", "dogs", "mountains", "bar", "foo"], | ||
theme: "Hyper Term Black", | ||
notifications: true, | ||
language: "en-US", | ||
movement: [ | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
{ x: 1, y: 2, z: 3 }, | ||
], | ||
const v1: Repo = { | ||
id: 132935648, | ||
node_id: "MDEwOlJlcG9zaXRvcnkxMzI5MzU2NDg=", | ||
name: "boysenberry-repo-1", | ||
full_name: "octocat/boysenberry-repo-1", | ||
private: true, | ||
owner: { | ||
login: "octocat", | ||
id: 583231, | ||
node_id: "MDQ6VXNlcjU4MzIzMQ==", | ||
avatar_url: "https://avatars.githubusercontent.com/u/583231?v=4", | ||
gravatar_id: "", | ||
url: "https://api.github.com/users/octocat", | ||
html_url: "https://github.com/octocat", | ||
followers_url: "https://api.github.com/users/octocat/followers", | ||
following_url: "https://api.github.com/users/octocat/following{/other_user}", | ||
gists_url: "https://api.github.com/users/octocat/gists{/gist_id}", | ||
starred_url: "https://api.github.com/users/octocat/starred{/owner}{/repo}", | ||
subscriptions_url: "https://api.github.com/users/octocat/subscriptions", | ||
organizations_url: "https://api.github.com/users/octocat/orgs", | ||
repos_url: "https://api.github.com/users/octocat/repos", | ||
events_url: "https://api.github.com/users/octocat/events{/privacy}", | ||
received_events_url: "https://api.github.com/users/octocat/received_events", | ||
type: "User", | ||
user_view_type: "public", | ||
site_admin: false, | ||
}, | ||
html_url: "https://github.com/octocat/boysenberry-repo-1", | ||
description: "Testing", | ||
fork: true, | ||
url: "https://api.github.com/repos/octocat/boysenberry-repo-1", | ||
forks_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/forks", | ||
keys_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/keys{/key_id}", | ||
collaborators_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/collaborators{/collaborator}", | ||
teams_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/teams", | ||
hooks_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/hooks", | ||
issue_events_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/issues/events{/number}", | ||
events_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/events", | ||
assignees_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/assignees{/user}", | ||
branches_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/branches{/branch}", | ||
tags_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/tags", | ||
blobs_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/git/blobs{/sha}", | ||
git_tags_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/git/tags{/sha}", | ||
git_refs_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/git/refs{/sha}", | ||
trees_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/git/trees{/sha}", | ||
statuses_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/statuses/{sha}", | ||
languages_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/languages", | ||
stargazers_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/stargazers", | ||
contributors_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/contributors", | ||
subscribers_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/subscribers", | ||
subscription_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/subscription", | ||
commits_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/commits{/sha}", | ||
git_commits_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/git/commits{/sha}", | ||
comments_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/comments{/number}", | ||
issue_comment_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/issues/comments{/number}", | ||
contents_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/contents/{+path}", | ||
compare_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/compare/{base}...{head}", | ||
merges_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/merges", | ||
archive_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/{archive_format}{/ref}", | ||
downloads_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/downloads", | ||
issues_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/issues{/number}", | ||
pulls_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/pulls{/number}", | ||
milestones_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/milestones{/number}", | ||
notifications_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/notifications{?since,all,participating}", | ||
labels_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/labels{/name}", | ||
releases_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/releases{/id}", | ||
deployments_url: "https://api.github.com/repos/octocat/boysenberry-repo-1/deployments", | ||
created_at: "2018-05-10T17:51:29Z", | ||
updated_at: "2025-05-24T02:01:19Z", | ||
pushed_at: "2024-05-26T07:02:05Z", | ||
git_url: "git://github.com/octocat/boysenberry-repo-1.git", | ||
ssh_url: "git@github.com:octocat/boysenberry-repo-1.git", | ||
clone_url: "https://github.com/octocat/boysenberry-repo-1.git", | ||
svn_url: "https://github.com/octocat/boysenberry-repo-1", | ||
homepage: "", | ||
size: 4, | ||
stargazers_count: 332, | ||
watchers_count: 332, | ||
language: null, | ||
has_issues: false, | ||
has_projects: true, | ||
has_downloads: true, | ||
has_wiki: true, | ||
has_pages: false, | ||
has_discussions: false, | ||
forks_count: 20, | ||
mirror_url: null, | ||
archived: false, | ||
disabled: false, | ||
open_issues_count: 1, | ||
license: null, | ||
allow_forking: true, | ||
is_template: false, | ||
web_commit_signoff_required: false, | ||
topics: [], | ||
visibility: "public", | ||
forks: 20, | ||
open_issues: 1, | ||
watchers: 332, | ||
default_branch: "master", | ||
}; | ||
const v2 = `{"id":2,"name":"Medium Object","age":18,"email":"me@jairus.dev","street":"I don't want to say my street","city":"I don't want to say this either","state":"It really depends","zip":"I forget what it is","tags":["me","dogs","mountains","bar","foo"],"theme":"Hyper Term Black","notifications":true,"language":"en-US","movement":[{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3}]}`; | ||
const v2 = `{"id":132935648,"node_id":"MDEwOlJlcG9zaXRvcnkxMzI5MzU2NDg=","name":"boysenberry-repo-1","full_name":"octocat/boysenberry-repo-1","private":true,"owner":{"login":"octocat","id":583231,"node_id":"MDQ6VXNlcjU4MzIzMQ==","avatar_url":"https://avatars.githubusercontent.com/u/583231?v=4","gravatar_id":"","url":"https://api.github.com/users/octocat","html_url":"https://github.com/octocat","followers_url":"https://api.github.com/users/octocat/followers","following_url":"https://api.github.com/users/octocat/following{/other_user}","gists_url":"https://api.github.com/users/octocat/gists{/gist_id}","starred_url":"https://api.github.com/users/octocat/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/octocat/subscriptions","organizations_url":"https://api.github.com/users/octocat/orgs","repos_url":"https://api.github.com/users/octocat/repos","events_url":"https://api.github.com/users/octocat/events{/privacy}","received_events_url":"https://api.github.com/users/octocat/received_events","type":"User","user_view_type":"public","site_admin":false},"html_url":"https://github.com/octocat/boysenberry-repo-1","description":"Testing","fork":true,"url":"https://api.github.com/repos/octocat/boysenberry-repo-1","forks_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/forks","keys_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/keys{/key_id}","collaborators_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/teams","hooks_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/hooks","issue_events_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/issues/events{/number}","events_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/events","assignees_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/assignees{/user}","branches_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/branches{/branch}","tags_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/tags","blobs_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/git/refs{/sha}","trees_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/git/trees{/sha}","statuses_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/statuses/{sha}","languages_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/languages","stargazers_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/stargazers","contributors_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/contributors","subscribers_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/subscribers","subscription_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/subscription","commits_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/commits{/sha}","git_commits_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/git/commits{/sha}","comments_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/comments{/number}","issue_comment_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/issues/comments{/number}","contents_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/contents/{+path}","compare_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/compare/{base}...{head}","merges_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/merges","archive_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/downloads","issues_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/issues{/number}","pulls_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/pulls{/number}","milestones_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/milestones{/number}","notifications_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/labels{/name}","releases_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/releases{/id}","deployments_url":"https://api.github.com/repos/octocat/boysenberry-repo-1/deployments","created_at":"2018-05-10T17:51:29Z","updated_at":"2025-05-24T02:01:19Z","pushed_at":"2024-05-26T07:02:05Z","git_url":"git://github.com/octocat/boysenberry-repo-1.git","ssh_url":"git@github.com:octocat/boysenberry-repo-1.git","clone_url":"https://github.com/octocat/boysenberry-repo-1.git","svn_url":"https://github.com/octocat/boysenberry-repo-1","homepage":"","size":4,"stargazers_count":332,"watchers_count":332,"language":null,"has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":20,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":1,"license":null,"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":[],"visibility":"public","forks":20,"open_issues":1,"watchers":332,"default_branch":"master"}`; | ||
expect(JSON.stringify(v1)).toBe(v2); | ||
expect(JSON.stringify(JSON.parse<LargeJSON>(v2))).toBe(v2) | ||
expect(JSON.stringify(JSON.parse<Repo>(v2))).toBe(v2); | ||
bench( | ||
@@ -127,3 +237,3 @@ "Serialize Large Object", | ||
}, | ||
2_000_00, | ||
100_00, | ||
); | ||
@@ -134,5 +244,5 @@ | ||
() => { | ||
JSON.parse<LargeJSON>(v2); | ||
JSON.parse<Repo>(v2); | ||
}, | ||
2_000_00, | ||
100_00, | ||
); |
@@ -120,3 +120,3 @@ import { JSON } from ".."; | ||
let code = load<u16>(srcStart); | ||
while (JSON.Util.isSpace(code)) code = load<u16>(srcStart += 2); | ||
while (JSON.Util.isSpace(code)) code = load<u16>((srcStart += 2)); | ||
if (keyStart == 0) { | ||
@@ -127,3 +127,3 @@ if (code == 34 && load<u16>(srcStart - 2) !== 92) { | ||
keyEnd = srcStart; | ||
while (JSON.Util.isSpace((code = load<u16>((srcStart += 2))))) { } | ||
while (JSON.Util.isSpace((code = load<u16>((srcStart += 2))))) {} | ||
if (code !== 58) throw new Error("Expected ':' after key at position " + (srcEnd - srcStart).toString()); | ||
@@ -147,11 +147,14 @@ isKey = false; | ||
const code16 = load<u16>(keyStart); | ||
if (code16 == 120) { // x | ||
if (code16 == 120) { | ||
// x | ||
store<f64>(changetype<usize>(out), JSON.__deserialize<f64>(lastIndex, srcStart), offsetof<this>("x")); | ||
keyStart = 0; | ||
break; | ||
} else if (code16 == 121) { // y | ||
} else if (code16 == 121) { | ||
// y | ||
store<f64>(changetype<usize>(out), JSON.__deserialize<f64>(lastIndex, srcStart), offsetof<this>("y")); | ||
keyStart = 0; | ||
break; | ||
} else if (code16 == 122) { // z | ||
} else if (code16 == 122) { | ||
// z | ||
store<f64>(changetype<usize>(out), JSON.__deserialize<f64>(lastIndex, srcStart), offsetof<this>("z")); | ||
@@ -158,0 +161,0 @@ keyStart = 0; |
@@ -0,10 +1,19 @@ | ||
let currentDescription: string = ""; | ||
export function describe(description: string, routine: () => void): void { | ||
currentDescription = description; | ||
routine(); | ||
// console.log(" " + description + " OK"); | ||
} | ||
export function expect(left: string): Expectation { | ||
return new Expectation(left); | ||
export function it(description: string, routine: () => void): void { | ||
currentDescription = description; | ||
routine(); | ||
} | ||
export function expect<T>(left: T): Expectation { | ||
// @ts-ignore | ||
if (!isDefined(left.toString)) throw new Error("Expected left to have a toString method, but it does not."); | ||
// @ts-ignore | ||
return new Expectation(left.toString()); | ||
} | ||
class Expectation { | ||
@@ -16,5 +25,10 @@ public left: string; | ||
} | ||
toBe(right: string): void { | ||
if (this.left != right) { | ||
console.log(" (expected) -> " + right); | ||
toBe<T>(right: T): void { | ||
// @ts-ignore | ||
if (!isDefined(right.toString)) throw new Error("Expected right to have a toString method, but it does not."); | ||
// @ts-ignore | ||
if (this.left != right.toString()) { | ||
console.log(" " + currentDescription + "\n"); | ||
// @ts-ignore | ||
console.log(" (expected) -> " + right.toString()); | ||
console.log(" (received) -> " + this.left); | ||
@@ -21,0 +35,0 @@ unreachable(); |
@@ -57,2 +57,4 @@ import { JSON } from ".."; | ||
expect(JSON.stringify(JSON.parse<Vec3>('{"x":3.4,"y":1.2,"z":8.3}'))).toBe('{"x":3.4,"y":1.2,"z":8.3}'); | ||
expect(JSON.stringify(JSON.parse<Vec3>('{"x":3.4,"a":1.3,"y":1.2,"z":8.3}'))).toBe('{"x":3.4,"y":1.2,"z":8.3}'); | ||
expect(JSON.stringify(JSON.parse<Vec3>('{"x":3.4,"a":1.3,"y":123,"asdf":3453204,"boink":[],"y":1.2,"z":8.3}'))).toBe('{"x":3.4,"y":1.2,"z":8.3}'); | ||
}); | ||
@@ -59,0 +61,0 @@ |
import { JSON } from "../"; | ||
import { describe, expect } from "./lib"; | ||
import { DerivedObject, Null, ObjWithStrangeKey, ObjectWithFloat, OmitIf, Player, Vec3 } from "./types"; | ||
// describe("Should serialize objects", () => { | ||
// expect( | ||
// JSON.stringify<Vec3>({ | ||
// x: 3.4, | ||
// y: 1.2, | ||
// z: 8.3, | ||
// }), | ||
// ).toBe('{"x":3.4,"y":1.2,"z":8.3}'); | ||
// expect( | ||
// JSON.stringify<Player>({ | ||
// firstName: "Emmet", | ||
// lastName: "West", | ||
// lastActive: [8, 27, 2022], | ||
// age: 23, | ||
// pos: { | ||
// x: 3.4, | ||
// y: 1.2, | ||
// z: 8.3, | ||
// }, | ||
// isVerified: true, | ||
// }), | ||
// ).toBe('{"firstName":"Emmet","lastName":"West","lastActive":[8,27,2022],"age":23,"pos":{"x":3.4,"y":1.2,"z":8.3},"isVerified":true}'); | ||
// expect(JSON.stringify<ObjectWithFloat>({ f: 7.23 })).toBe('{"f":7.23}'); | ||
// expect(JSON.stringify<ObjectWithFloat>({ f: 0.000001 })).toBe('{"f":0.000001}'); | ||
// expect(JSON.stringify<ObjectWithFloat>({ f: 1e-7 })).toBe('{"f":1e-7}'); | ||
// expect(JSON.stringify<ObjectWithFloat>({ f: 1e20 })).toBe('{"f":100000000000000000000.0}'); | ||
// expect(JSON.stringify<ObjectWithFloat>({ f: 1e21 })).toBe('{"f":1e+21}'); | ||
// expect(JSON.stringify<ObjWithStrangeKey<string>>({ data: "foo" })).toBe('{"a\\\\\\t\\"\\u0002b`c":"foo"}'); | ||
// }); | ||
// describe("Should serialize @omit'ed objects", () => { | ||
// expect( | ||
// JSON.stringify(<OmitIf>{ | ||
// y: 1, | ||
// }), | ||
// ).toBe('{"x":1,"y":1,"z":1}'); | ||
// }); | ||
// describe("Should deserialize class inheritance", () => { | ||
// const jsonStr = '{"a":"1","b":"2"}'; | ||
// const obj = JSON.parse<DerivedObject>(jsonStr); | ||
// expect((obj instanceof DerivedObject).toString()).toBe("true"); | ||
// expect(obj.a).toBe("1"); | ||
// expect(obj.b).toBe("2"); | ||
// }); | ||
// describe("Should deserialize nulls", () => { | ||
// expect(JSON.stringify(JSON.parse<Null>("null"))).toBe("null"); | ||
// }); | ||
// describe("Should deserialize integer arrays", () => { | ||
// expect(JSON.stringify(JSON.parse<u32[]>("[0,100,101]"))).toBe(JSON.stringify([0, 100, 101])); | ||
// expect(JSON.stringify(JSON.parse<i32[]>("[0,100,101,-100,-101]"))).toBe(JSON.stringify([0, 100, 101, -100, -101])); | ||
// }); | ||
// describe("Should deserialize float arrays", () => { | ||
// expect(JSON.stringify(JSON.parse<f64[]>("[7.23,1000.0,1000.0,1.23456,1.23456,0.0,7.23]"))).toBe(JSON.stringify([7.23, 1000.0, 1000.0, 1.23456, 1.23456, 0.0, 7.23])); | ||
// expect(JSON.stringify(JSON.parse<f64[]>("[1e+21,1e+22,1e-7,1e-8,1e-9]"))).toBe(JSON.stringify([1e21, 1e22, 1e-7, 1e-8, 1e-9])); | ||
// }); | ||
// describe("Should deserialize boolean arrays", () => { | ||
// expect(JSON.stringify(JSON.parse<boolean[]>("[true,false]"))).toBe(JSON.stringify([true, false])); | ||
// }); | ||
// describe("Should deserialize string arrays", () => { | ||
// expect(JSON.stringify(JSON.parse<string[]>('["string \\"with random spa\\nces and \\nnewlines\\n\\n\\n"]'))).toBe(JSON.stringify(['string "with random spa\nces and \nnewlines\n\n\n'])); | ||
// }); | ||
// describe("Should deserialize nested integer arrays", () => { | ||
// expect(JSON.stringify(JSON.parse<i64[][]>("[[100,101],[-100,-101],[0]]"))).toBe(JSON.stringify([[100, 101], [-100, -101], [0]])); | ||
// }); | ||
// describe("Should deserialize nested float arrays", () => { | ||
// expect(JSON.stringify(JSON.parse<f64[][]>("[[7.23],[1000.0],[1000.0],[1.23456],[1.23456],[0.0],[7.23]]"))).toBe(JSON.stringify([[7.23], [1000.0], [1000.0], [1.23456], [1.23456], [0.0], [7.23]])); | ||
// }); | ||
// describe("Should deserialize nested boolean arrays", () => { | ||
// expect(JSON.stringify(JSON.parse<boolean[][]>("[[true],[false]]"))).toBe(JSON.stringify([[true], [false]])); | ||
// }); | ||
// describe("Should deserialize object arrays", () => { | ||
// expect(JSON.stringify(JSON.parse<Vec3[]>('[{"x":3.4,"y":1.2,"z":8.3},{"x":3.4,"y":-2.1,"z":9.3}]'))).toBe( | ||
// JSON.stringify(<Vec3[]>[ | ||
// { x: 3.4, y: 1.2, z: 8.3 }, | ||
// { x: 3.4, y: -2.1, z: 9.3 }, | ||
// ]), | ||
// ); | ||
// }); | ||
// describe("Should deserialize Objects", () => { | ||
// expect(JSON.stringify(JSON.parse<Vec3>('{"x":3.4,"y":1.2,"z":8.3}'))).toBe(JSON.stringify(<Vec3>{ x: 3.4, y: 1.2, z: 8.3 })); | ||
// expect(JSON.stringify(JSON.parse<Player>('{"firstName":"Emmet","lastName":"West","lastActive":[8,27,2022],"age":23,"pos":{"x":3.4,"y":1.2,"z":8.3},"isVerified":true}'))).toBe( | ||
// JSON.stringify(<Player>{ | ||
// firstName: "Emmet", | ||
// lastName: "West", | ||
// lastActive: [8, 27, 2022], | ||
// age: 23, | ||
// pos: { x: 3.4, y: 1.2, z: 8.3 }, | ||
// isVerified: true, | ||
// }), | ||
// ); | ||
// expect(JSON.stringify(JSON.parse<ObjectWithFloat>('{"f":7.23}'))).toBe(JSON.stringify(<ObjectWithFloat>{ f: 7.23 })); | ||
// expect(JSON.stringify(JSON.parse<ObjectWithFloat>('{"f":0.000001}'))).toBe(JSON.stringify(<ObjectWithFloat>{ f: 0.000001 })); | ||
// expect(JSON.stringify(JSON.parse<ObjWithStrangeKey<string>>('{"a\\\\\\t\\"\\u0002b`c":"foo"}'))).toBe(JSON.stringify(<ObjWithStrangeKey<string>>{ data: "foo" })); | ||
// }); |
@@ -427,3 +427,3 @@ /// <reference path="./index.d.ts" /> | ||
constructor() { } | ||
constructor() {} | ||
@@ -630,3 +630,3 @@ // @ts-ignore: decorator | ||
} | ||
namespace Util { | ||
export namespace Util { | ||
// @ts-ignore: decorator | ||
@@ -633,0 +633,0 @@ @inline export function isSpace(code: u16): boolean { |
import { JSON } from "."; | ||
import { bytes } from "./util"; | ||
import { expect, it } from "./__tests__/lib"; | ||
// @json | ||
// class Obj { | ||
// public a: string = "hello"; | ||
// public b: string = "world"; | ||
// public c: string = '"\t\f\u0000\u0001'; | ||
// } | ||
it("should parse", () => { | ||
const str = `{ | ||
"id": "chatcmpl-BbvlnP0ESWa8OForeEjt7AkoIuh3Q", | ||
"object": "chat.completion", | ||
"created": 1748379903, | ||
"model": "gpt-4o-mini-2024-07-18", | ||
"choices": [ | ||
{ | ||
"index": 0, | ||
"message": { | ||
"role": "assistant", | ||
"content": "Hello! How can I assist you today?", | ||
"refusal": null, | ||
"annotations": [] | ||
}, | ||
"logprobs": null, | ||
"finish_reason": "stop" | ||
} | ||
], | ||
"usage": { | ||
"prompt_tokens": 15, | ||
"completion_tokens": 9, | ||
"total_tokens": 24, | ||
"prompt_tokens_details": { | ||
"cached_tokens": 0, | ||
"audio_tokens": 0 | ||
}, | ||
"completion_tokens_details": { | ||
"reasoning_tokens": 0, | ||
"audio_tokens": 0, | ||
"accepted_prediction_tokens": 0, | ||
"rejected_prediction_tokens": 0 | ||
} | ||
}, | ||
"service_tier": "default", | ||
"system_fingerprint": "fp_34a54ae93c" | ||
}`; | ||
// @json | ||
// class Vec3 { | ||
// x: f32 = 0.0; | ||
// y: f32 = 0.0; | ||
// z: f32 = 0.0; | ||
// } | ||
const output = JSON.parse<OpenAIChatOutput>(str); | ||
// @json | ||
// class Player { | ||
// @alias("first name") | ||
// firstName!: string; | ||
// lastName!: string; | ||
// lastActive!: i32[]; | ||
// // Drop in a code block, function, or expression that evaluates to a boolean | ||
// @omitif((self: Player) => self.age < 18) | ||
// age!: i32; | ||
expect(output.id).toBe("chatcmpl-BbvlnP0ESWa8OForeEjt7AkoIuh3Q"); | ||
expect(output.object).toBe("chat.completion"); | ||
expect(output.model).toBe("gpt-4o-mini-2024-07-18"); | ||
expect(output.system_fingerprint).toBe("fp_34a54ae93c"); // fails ("") | ||
}); | ||
// @omitnull() | ||
// pos!: Vec3 | null; | ||
// isVerified!: boolean; | ||
// } | ||
// @json | ||
// class Point { } | ||
// @json | ||
// class NewPoint { | ||
// x: f64 = 0.0; | ||
// y: f64 = 0.0; | ||
// constructor(x: f64, y: f64) { | ||
// this.x = x; | ||
// this.y = y; | ||
// } | ||
// @serializer | ||
// serializer(self: NewPoint): string { | ||
// return `x=${self.x},y=${self.y}`; | ||
// } | ||
// @deserializer | ||
// deserializer(data: string): NewPoint { | ||
// const dataSize = bytes(data); | ||
// const c = data.indexOf(","); | ||
// const x = data.slice(2, c); | ||
// const y = data.slice(c + 3); | ||
// return new NewPoint(f64.parse(x), f64.parse(y)); | ||
// } | ||
// } | ||
// @json | ||
// class InnerObj<T> { | ||
// obj: T = instantiate<T>(); | ||
// } | ||
// @json | ||
// class ObjWithBracketString { | ||
// data: string = ""; | ||
// } | ||
// const player: Player = { | ||
// firstName: "Jairus", | ||
// lastName: "Tanaka", | ||
// lastActive: [2, 7, 2025], | ||
// age: 18, | ||
// pos: { | ||
// x: 3.4, | ||
// y: 1.2, | ||
// z: 8.3, | ||
// }, | ||
// isVerified: true, | ||
// }; | ||
// const a1 = JSON.stringify("\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000a\u000b\u000c\u000d\u000e\u000f\u000f\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f"); | ||
// // console.log("Bytes " + bytes(a1).toString()); | ||
// console.log("a1: " + a1); | ||
// const obj = new Obj(); | ||
// const a2 = JSON.stringify(obj); | ||
// // console.log("Bytes " + bytes(a2).toString()); | ||
// console.log("a2: " + a2); | ||
// const a3 = JSON.stringify(player); | ||
// // console.log("Bytes " + bytes(a3).toString()); | ||
// console.log("a3: " + a3); | ||
// const a4 = new JSON.Obj(); | ||
// a4.set("x", 1.5); | ||
// a4.set("y", 5.4); | ||
// a4.set("z", 9.8); | ||
// a4.set("obj", obj); | ||
// a4.set<boolean>("bool", false); | ||
// console.log("a4: " + JSON.stringify(a4)); | ||
// const a5 = JSON.parse<JSON.Obj>('{"foo":"bar"}'); | ||
// console.log("a5: " + JSON.stringify(a5)); | ||
// const a6 = JSON.parse<JSON.Obj>('{"x":1.5,"y":5.4,"z":9.8,"obj":{"foo":"bar"}}'); | ||
// console.log("a6: " + JSON.stringify(a6)); | ||
// const a7 = JSON.parse<JSON.Value[]>('["string",true,3.14,{"x":1.0,"y":2.0,"z":3.0},[1,2,3,true]]'); | ||
// console.log("a7: " + JSON.stringify(a7)); | ||
// const a8 = JSON.stringify(["hello", JSON.stringify("world"), "working?"]); | ||
// console.log("a8: " + a8); | ||
// const a9 = JSON.stringify<JSON.Raw>(JSON.Raw.from('"hello world"')); | ||
// console.log("a9: " + a9); | ||
// const m10 = new Map<string, JSON.Raw>(); | ||
// m10.set("hello", new JSON.Raw('"world"')); | ||
// m10.set("pos", new JSON.Raw('{"x":1.0,"y":2.0,"z":3.0}')); | ||
// const a10 = JSON.stringify(m10); | ||
// console.log("a10: " + a10); | ||
// const a11 = JSON.parse<JSON.Obj>(' { "x" : 3.4 , "y" : 1.2 , "z" : 8.3 } '); | ||
// console.log("a11: " + JSON.stringify(a11)); | ||
// const a12 = JSON.parse<InnerObj<ObjWithBracketString>>('{"obj":{"data":"hello} world"}}'); | ||
// console.log("a12: " + JSON.stringify(a12)); | ||
// const a13 = JSON.stringify<JSON.Obj>(new JSON.Obj()); | ||
// console.log("a13: " + a13); | ||
// const a14 = JSON.stringify(new Point()); | ||
// console.log("a14: " + a14); | ||
// const a15 = JSON.parse<Point>(a14); | ||
// console.log("a15: " + JSON.stringify(a15)); | ||
// const a16 = JSON.stringify(new NewPoint(1.0, 2.0)); | ||
// console.log("a16: " + a16); | ||
// const a17 = JSON.parse<NewPoint>(a16); | ||
// console.log("a17: " + JSON.stringify(a17)); | ||
// const a18 = JSON.parse<JSON.Obj[]>('[{"x":1.0,"y":2.0,"z":3.0},{"x":4.0,"y":5.0,"z":6.0},{"x":7.0,"y":8.0,"z":9.0}]'); | ||
// console.log("a18: " + JSON.stringify(a18)); | ||
// const a19 = JSON.stringify<JSON.Obj[]>(a18); | ||
// console.log("a19: " + a19); | ||
// const a20 = JSON.parse<JSON.Box<f64>[]>("[1.3,4.7,9.5]"); | ||
// console.log("a20: " + JSON.stringify(a20)); | ||
// const a21 = JSON.stringify<JSON.Box<f64>[]>(a20); | ||
// console.log("a21: " + a21); | ||
// const a22 = JSON.parse<Foo>('{"id":"0xb8","firstName":"Jairus","lastName":"Tanaka"}'); | ||
// console.log("a22: " + JSON.stringify(a22)); | ||
// @json | ||
// class Foo { | ||
// id: string = ""; | ||
// firstName: string = ""; | ||
// lastName: string = ""; | ||
// } | ||
// @json | ||
// class SrvInfo { | ||
// accessUrl: string = "https://example.com"; | ||
// cardTypes: i32[] = [1, 2, 3]; | ||
// customService: string = "Contact us at support@example.com"; | ||
// invoiceApplicationStatus: i32 = 1; | ||
// isCertification: bool = true; | ||
// isOnlineRecharge: bool = false; | ||
// loginTypes: i32[] = [0, 1]; // e.g. 0 = password, 1 = OTP | ||
// record: string = "ICP 12345678"; | ||
// regCompanyAudit: i32 = 2; | ||
// regCompanyPipeline: i32[] = [101, 102, 103]; | ||
// regPwdLimit: i32 = 8; // min password length | ||
// serverTime: i64 = 1650000000000; // dummy timestamp | ||
// srvDescription: string = "A demo service for handling customer operations."; | ||
// srvHiddenMenu: string[] = ["admin", "beta"]; | ||
// srvHost: string = "srv.example.com"; | ||
// srvId: i32 = 999; | ||
// srvKeywords: string[] = ["finance", "payments", "online"]; | ||
// srvLogoImgUrl: string = "https://example.com/logo.png"; | ||
// srvName: string = "ExampleService"; | ||
// srvPageId: i32 = 5; | ||
// thirdAuthUrl: string = "https://auth.example.com"; | ||
// userCenterStyle: i32 = 1; // e.g. 1 = modern, 0 = legacy | ||
// } | ||
// const a23 = JSON.stringify(new SrvInfo()); | ||
// console.log("a23: " + a23); | ||
// const a24 = '{"accessUrl":"https://example.com","cardTypes":[1,2,3],"customService":"Contact us at support@example.com","invoiceApplicationStatus":1,"isCertification":true,"isOnlineRecharge":false,"loginTypes":[0,1],"record":"ICP 12345678","regCompanyAudit":2,"regCompanyPipeline":[101,102,103],"regPwdLimit":8,"serverTime":1650000000000,"srvDescription":"A demo service for handling customer operations.","srvHiddenMenu":["admin","beta"],"srvHost":"srv.example.com","srvId":999,"srvKeywords":["finance","payments","online"],"srvLogoImgUrl":"https://example.com/logo.png","srvName":"ExampleService","srvPageId":5,"thirdAuthUrl":"https://auth.example.com","userCenterStyle":1}'; | ||
// console.log("a25: " + (a24 == a23).toString()); | ||
// const a26 = JSON.parse<SrvInfo>(a23); | ||
// console.log("a26: " + JSON.stringify(a26)); | ||
// console.log("a27: " + (JSON.stringify(a26) == a23).toString()) | ||
import { | ||
bs | ||
} from "../lib/as-bs" | ||
@json | ||
class GenericEnum<T> { | ||
private tag: string = "" | ||
private value: T | null = null | ||
constructor() { | ||
this.tag = "" | ||
this.value = null | ||
} | ||
static create<T>(tag: string, value: T): GenericEnum<T> { | ||
const item = new GenericEnum<T>() | ||
item.tag = tag | ||
item.value = value | ||
return item | ||
} | ||
getTag(): string { | ||
return this.tag | ||
} | ||
getValue(): T | null { | ||
return this.value | ||
} | ||
@serializer | ||
serialize<T>(self: GenericEnum<T>): string { | ||
const tagJson = JSON.stringify(self.tag); | ||
const valueJson = JSON.stringify(self.value); | ||
return `{${tagJson}:${valueJson}}` | ||
} | ||
@deserializer | ||
deserialize(data: string): GenericEnum<T> { | ||
const parsed = JSON.parse<Map<string, JSON.Raw>>(data); | ||
const result = new GenericEnum<T>(); | ||
const keys = parsed.keys(); | ||
const values = parsed.values(); | ||
result.tag = keys[0]; | ||
result.value = JSON.parse<T>(values[0].data); | ||
return result; | ||
} | ||
class OpenAIChatOutput { | ||
id!: string; | ||
object!: string; | ||
model!: string; | ||
system_fingerprint!: string; | ||
} | ||
@json | ||
class Node<T> { | ||
name: string | ||
id: u32 | ||
data: T | ||
constructor() { | ||
this.name = "" | ||
this.id = 0 | ||
this.data = changetype<T>(0); | ||
} | ||
} | ||
const enumValue = GenericEnum.create<string>("success", "Hello World") | ||
const node = new Node<GenericEnum<string>>(); | ||
node.name = "test-node"; | ||
node.id = 42; | ||
node.data = enumValue; | ||
const serialized = JSON.stringify(node); | ||
console.log("Serialized Node: " + serialized); | ||
const deserialized = JSON.parse<JSON.Obj>(serialized) | ||
console.log("Deserialized Node: " + JSON.stringify(deserialized)); |
# Change Log | ||
## 2025-05-27 - 1.1.9 | ||
- change: strict mode is disabled by default. Enable it with JSON_STRICT=true | ||
- fix: should ignore properties of same length and type if no matching key exists | ||
- fix: should ignore properties of different type if no matching key exists | ||
- fix: should ignore complex properties if no matching key exists | ||
## 2025-05-27 - 1.1.8 | ||
@@ -4,0 +11,0 @@ |
@@ -1,1 +0,1 @@ | ||
export { JSON } from "./assembly/index"; | ||
export { JSON } from "./assembly/index"; |
{ | ||
"name": "json-as", | ||
"version": "1.1.8", | ||
"version": "1.1.9", | ||
"author": "Jairus Tanaka", | ||
@@ -5,0 +5,0 @@ "description": "The only JSON library you'll need for AssemblyScript. SIMD enabled", |
@@ -9,3 +9,3 @@ <h6 align="center"> | ||
</span> | ||
AssemblyScript - v1.1.8 | ||
AssemblyScript - v1.1.9 | ||
</pre> | ||
@@ -388,3 +388,3 @@ </h6> | ||
| Medium Object | 494 bytes | 4,060,913 ops/s | 1,396,160 ops/s | 2,006 MB/s | 689.7 MB/s | | ||
| Large Object | 3374 bytes | 614,754 ops/s | 132,802 ops/s | 2,074 MB/s | 448.0 MB/s | | ||
| Large Object | 3374 bytes | 479,616 ops/s | 132,802 ops/s | 2,074 MB/s | 448.0 MB/s | | ||
@@ -391,0 +391,0 @@ **Table 2** - _JavaScript (V8)_ |
@@ -11,3 +11,3 @@ import { Node } from "assemblyscript/dist/assemblyscript.js"; | ||
const DEBUG = process.env["JSON_DEBUG"]; | ||
const STRICT = !(process.env["JSON_STRICT"] && process.env["JSON_STRICT"] == "false"); | ||
const STRICT = process.env["JSON_STRICT"] && process.env["JSON_STRICT"] == "true"; | ||
class CustomTransform extends Visitor { | ||
@@ -342,3 +342,3 @@ static SN = new CustomTransform(); | ||
DESERIALIZE += indent + " let isKey = false;\n"; | ||
if (sortedMembers.object.length || sortedMembers.array.length) | ||
if (!STRICT || sortedMembers.object.length || sortedMembers.array.length) | ||
DESERIALIZE += indent + " let depth: i32 = 0;\n"; | ||
@@ -381,3 +381,3 @@ DESERIALIZE += indent + " let lastIndex: usize = 0;\n\n"; | ||
return [...groups.values()] | ||
.map(group => group.sort((a, b) => { | ||
.map((group) => group.sort((a, b) => { | ||
const aLen = (a.alias || a.name).length; | ||
@@ -389,14 +389,42 @@ const bLen = (b.alias || b.name).length; | ||
}; | ||
const generateGroups = (members, cb, nil = false) => { | ||
const groups = groupMembers(members); | ||
DESERIALIZE += " switch (<u32>keyEnd - <u32>keyStart) {\n"; | ||
for (const group of groups) { | ||
const groupLen = (group[0].alias || group[0].name).length << 1; | ||
DESERIALIZE += " case " + groupLen + ": {\n"; | ||
cb(group); | ||
DESERIALIZE += "\n }\n"; | ||
const generateGroups = (members, cb, type) => { | ||
if (!members.length) { | ||
if (STRICT) { | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
} | ||
else { | ||
if (type == "string") | ||
DESERIALIZE += indent + " srcStart += 4;\n"; | ||
else | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
if (type != "boolean" && type != "null") | ||
DESERIALIZE += indent + " break;\n"; | ||
} | ||
} | ||
DESERIALIZE += " }\n"; | ||
if (!members[0].node.type.isNullable && !isBoolean(members[0].type)) | ||
DESERIALIZE += " break;\n"; | ||
else { | ||
const groups = groupMembers(members); | ||
DESERIALIZE += " switch (<u32>keyEnd - <u32>keyStart) {\n"; | ||
for (const group of groups) { | ||
const groupLen = (group[0].alias || group[0].name).length << 1; | ||
DESERIALIZE += " case " + groupLen + ": {\n"; | ||
cb(group); | ||
DESERIALIZE += "\n }\n"; | ||
} | ||
DESERIALIZE += " default: {\n"; | ||
if (STRICT) { | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
} | ||
else { | ||
if (type == "string") | ||
DESERIALIZE += indent + " srcStart += 4;\n"; | ||
else | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
} | ||
DESERIALIZE += " }\n"; | ||
DESERIALIZE += " }\n"; | ||
if (!members[0].node.type.isNullable && !isBoolean(members[0].type)) | ||
DESERIALIZE += " break;\n"; | ||
} | ||
}; | ||
@@ -445,8 +473,18 @@ const generateComparisions = (members) => { | ||
DESERIALIZE += " else {\n"; | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key in JSON object \'" + String.fromCharCode(load<u16>(srcStart)) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
DESERIALIZE += indent + " }\n"; | ||
} | ||
else { | ||
DESERIALIZE += " else {\n"; | ||
if (isString(members[0].type)) | ||
DESERIALIZE += indent + " srcStart += 4;\n"; | ||
else if (!complex) | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " break;\n"; | ||
DESERIALIZE += indent + " }\n"; | ||
} | ||
}; | ||
let mbElse = " "; | ||
if (sortedMembers.string.length) { | ||
if (!STRICT || sortedMembers.string.length) { | ||
DESERIALIZE += mbElse + "if (code == 34) {\n"; | ||
@@ -458,3 +496,3 @@ DESERIALIZE += " lastIndex = srcStart;\n"; | ||
DESERIALIZE += " if (code == 34 && load<u16>(srcStart - 2) !== 92) {\n"; | ||
generateGroups(sortedMembers.string, generateComparisions); | ||
generateGroups(sortedMembers.string, generateComparisions, "string"); | ||
DESERIALIZE += " }\n"; | ||
@@ -466,3 +504,3 @@ DESERIALIZE += " srcStart += 2;\n"; | ||
} | ||
if (sortedMembers.number.length) { | ||
if (!STRICT || sortedMembers.number.length) { | ||
DESERIALIZE += mbElse + "if (code - 48 <= 9 || code == 45) {\n"; | ||
@@ -474,3 +512,3 @@ DESERIALIZE += " lastIndex = srcStart;\n"; | ||
DESERIALIZE += " if (code == 44 || code == 125 || JSON.Util.isSpace(code)) {\n"; | ||
generateGroups(sortedMembers.number, generateComparisions); | ||
generateGroups(sortedMembers.number, generateComparisions, "number"); | ||
DESERIALIZE += " }\n"; | ||
@@ -482,3 +520,3 @@ DESERIALIZE += " srcStart += 2;\n"; | ||
} | ||
if (sortedMembers.object.length) { | ||
if (!STRICT || sortedMembers.object.length) { | ||
DESERIALIZE += mbElse + "if (code == 123) {\n"; | ||
@@ -497,3 +535,3 @@ DESERIALIZE += " lastIndex = srcStart;\n"; | ||
indent = " "; | ||
generateGroups(sortedMembers.object, generateComparisions); | ||
generateGroups(sortedMembers.object, generateComparisions, "object"); | ||
indent = ""; | ||
@@ -507,3 +545,3 @@ DESERIALIZE += " }\n"; | ||
} | ||
if (sortedMembers.array.length) { | ||
if (!STRICT || sortedMembers.array.length) { | ||
DESERIALIZE += mbElse + "if (code == 91) {\n"; | ||
@@ -522,3 +560,3 @@ DESERIALIZE += " lastIndex = srcStart;\n"; | ||
indent = " "; | ||
generateGroups(sortedMembers.array, generateComparisions); | ||
generateGroups(sortedMembers.array, generateComparisions, "array"); | ||
indent = ""; | ||
@@ -532,3 +570,3 @@ DESERIALIZE += " }\n"; | ||
} | ||
if (sortedMembers.boolean.length) { | ||
if (!STRICT || sortedMembers.boolean.length) { | ||
DESERIALIZE += mbElse + "if (code == 116) {\n"; | ||
@@ -554,8 +592,8 @@ DESERIALIZE += " if (load<u64>(srcStart) == 28429475166421108) {\n"; | ||
const firstMemberName = group[0].alias || group[0].name; | ||
DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n"; | ||
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " break;\n"; | ||
DESERIALIZE += indent + " }"; | ||
DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n"; | ||
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " break;\n"; | ||
DESERIALIZE += indent + " }"; | ||
for (let i = 1; i < group.length; i++) { | ||
@@ -565,3 +603,3 @@ const member = group[i]; | ||
DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n"; | ||
DESERIALIZE += indent + " store<" + member.type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(member.name) + "));\n"; | ||
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(member.name) + "));\n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
@@ -574,9 +612,21 @@ DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += " else {\n"; | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key in JSON object \'" + String.fromCharCode(load<u16>(srcStart)) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
DESERIALIZE += indent + " }\n"; | ||
} | ||
}); | ||
else { | ||
DESERIALIZE += " else { \n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " break;\n"; | ||
DESERIALIZE += indent + " }\n"; | ||
} | ||
}, "boolean"); | ||
DESERIALIZE += " }"; | ||
DESERIALIZE += " else {\n"; | ||
DESERIALIZE += " throw new Error(\"Expected to find 'true' but found '\" + JSON.Util.ptrToStr(lastIndex, srcStart) + \"' instead at position \" + (srcEnd - srcStart).toString());\n"; | ||
DESERIALIZE += " }"; | ||
DESERIALIZE += "\n }"; | ||
mbElse = " else "; | ||
DESERIALIZE += " else if (load<u64>(srcStart, 2) == 28429466576093281) {\n"; | ||
DESERIALIZE += mbElse + "if (code == 102) {\n"; | ||
DESERIALIZE += " if (load<u64>(srcStart, 2) == 28429466576093281) {\n"; | ||
DESERIALIZE += " srcStart += 10;\n"; | ||
@@ -610,3 +660,3 @@ generateGroups(sortedMembers.boolean, (group) => { | ||
DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n"; | ||
DESERIALIZE += indent + " store<" + member.type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(member.name) + "));\n"; | ||
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(member.name) + "));\n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
@@ -619,10 +669,21 @@ DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += " else {\n"; | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key in JSON object \'" + String.fromCharCode(load<u16>(srcStart)) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
DESERIALIZE += indent + " }\n"; | ||
} | ||
}); | ||
DESERIALIZE += " }\n"; | ||
DESERIALIZE += " }"; | ||
else { | ||
DESERIALIZE += " else { \n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " break;\n"; | ||
DESERIALIZE += indent + " }\n"; | ||
} | ||
}, "boolean"); | ||
DESERIALIZE += " }"; | ||
DESERIALIZE += " else {\n"; | ||
DESERIALIZE += " throw new Error(\"Expected to find 'false' but found '\" + JSON.Util.ptrToStr(lastIndex, srcStart) + \"' instead at position \" + (srcEnd - srcStart).toString());\n"; | ||
DESERIALIZE += " }"; | ||
DESERIALIZE += "\n }"; | ||
mbElse = " else "; | ||
} | ||
if (sortedMembers.null.length) { | ||
if (!STRICT || sortedMembers.null.length) { | ||
DESERIALIZE += mbElse + "if (code == 110) {\n"; | ||
@@ -658,3 +719,3 @@ DESERIALIZE += " if (load<u64>(srcStart) == 30399761348886638) {\n"; | ||
DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n"; | ||
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), null, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n"; | ||
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), null, offsetof<this>(" + JSON.stringify(member.name) + "));\n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
@@ -667,6 +728,13 @@ DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += " else {\n"; | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key in JSON object \'" + String.fromCharCode(load<u16>(srcStart)) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
DESERIALIZE += indent + " }\n"; | ||
} | ||
}, true); | ||
else { | ||
DESERIALIZE += " else { \n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " break;\n"; | ||
DESERIALIZE += indent + " }\n"; | ||
} | ||
}, "null"); | ||
DESERIALIZE += " }"; | ||
@@ -678,2 +746,3 @@ DESERIALIZE += "\n }"; | ||
DESERIALIZE += " srcStart += 2;\n"; | ||
DESERIALIZE += " keyStart = 0;\n"; | ||
DESERIALIZE += "}\n"; | ||
@@ -680,0 +749,0 @@ DESERIALIZE += "\n }\n"; |
@@ -13,3 +13,3 @@ import { ClassDeclaration, FieldDeclaration, IdentifierExpression, Parser, Source, NodeKind, CommonFlags, ImportStatement, Node, Tokenizer, SourceKind, NamedTypeNode, Range, FEATURE_SIMD, FunctionExpression, MethodDeclaration, Statement, Program, Feature, CallExpression, PropertyAccessExpression } from "assemblyscript/dist/assemblyscript.js"; | ||
const DEBUG = process.env["JSON_DEBUG"]; | ||
const STRICT = !(process.env["JSON_STRICT"] && process.env["JSON_STRICT"] == "false"); | ||
const STRICT = process.env["JSON_STRICT"] && process.env["JSON_STRICT"] == "true"; | ||
@@ -21,3 +21,2 @@ class CustomTransform extends Visitor { | ||
visitCallExpression(node: CallExpression) { | ||
super.visit(node.args, node); | ||
@@ -28,10 +27,6 @@ if (node.expression.kind != NodeKind.PropertyAccess || (node.expression as PropertyAccessExpression).property.text != "stringify") return; | ||
if (this.modify) { | ||
(node.expression as PropertyAccessExpression).expression = Node.createPropertyAccessExpression( | ||
Node.createIdentifierExpression("JSON", node.expression.range), | ||
Node.createIdentifierExpression("internal", node.expression.range), | ||
node.expression.range | ||
); | ||
(node.expression as PropertyAccessExpression).expression = Node.createPropertyAccessExpression(Node.createIdentifierExpression("JSON", node.expression.range), Node.createIdentifierExpression("internal", node.expression.range), node.expression.range); | ||
} | ||
this.modify = true; | ||
// console.log(toString(node)); | ||
@@ -104,3 +99,3 @@ // console.log(SimpleParser.parseStatement("JSON.internal.stringify").expression.expression) | ||
const hasCall = CustomTransform.hasCall(serializer); | ||
CustomTransform.visit(serializer); | ||
@@ -382,3 +377,3 @@ | ||
DESERIALIZE += indent + " let isKey = false;\n"; | ||
if (sortedMembers.object.length || sortedMembers.array.length) DESERIALIZE += indent + " let depth: i32 = 0;\n"; | ||
if (!STRICT || sortedMembers.object.length || sortedMembers.array.length) DESERIALIZE += indent + " let depth: i32 = 0;\n"; | ||
DESERIALIZE += indent + " let lastIndex: usize = 0;\n\n"; | ||
@@ -433,3 +428,3 @@ | ||
return [...groups.values()] | ||
.map(group => | ||
.map((group) => | ||
group.sort((a, b) => { | ||
@@ -439,3 +434,3 @@ const aLen = (a.alias || a.name).length; | ||
return aLen - bLen; | ||
}) | ||
}), | ||
) | ||
@@ -481,18 +476,37 @@ .sort((a, b) => b.length - a.length); | ||
const generateGroups = (members: Property[], cb: (group: Property[]) => void, type: "string" | "array" | "object" | "number" | "boolean" | "null") => { | ||
if (!members.length) { | ||
if (STRICT) { | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
} else { | ||
if (type == "string") DESERIALIZE += indent + " srcStart += 4;\n"; | ||
else DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
if (type != "boolean" && type != "null") DESERIALIZE += indent + " break;\n"; | ||
} | ||
} else { | ||
const groups = groupMembers(members); | ||
DESERIALIZE += " switch (<u32>keyEnd - <u32>keyStart) {\n"; | ||
const generateGroups = (members: Property[], cb: (group: Property[]) => void, nil: boolean = false) => { | ||
const groups = groupMembers(members); | ||
DESERIALIZE += " switch (<u32>keyEnd - <u32>keyStart) {\n"; | ||
for (const group of groups) { | ||
const groupLen = (group[0].alias || group[0].name).length << 1; | ||
DESERIALIZE += " case " + groupLen + ": {\n"; | ||
cb(group); | ||
DESERIALIZE += "\n }\n"; | ||
} | ||
for (const group of groups) { | ||
const groupLen = (group[0].alias || group[0].name).length << 1 | ||
DESERIALIZE += " case " + groupLen + ": {\n"; | ||
cb(group); | ||
DESERIALIZE += "\n }\n"; | ||
DESERIALIZE += " default: {\n"; | ||
if (STRICT) { | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
} else { | ||
if (type == "string") DESERIALIZE += indent + " srcStart += 4;\n"; | ||
else DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
} | ||
DESERIALIZE += " }\n"; | ||
DESERIALIZE += " }\n"; | ||
if (!members[0].node.type.isNullable && !isBoolean(members[0].type)) DESERIALIZE += " break;\n"; | ||
} | ||
}; | ||
DESERIALIZE += " }\n"; | ||
if (!members[0].node.type.isNullable && !isBoolean(members[0].type)) DESERIALIZE += " break;\n"; | ||
} | ||
const generateComparisions = (members: Property[]) => { | ||
@@ -539,4 +553,11 @@ if (members.some((m) => (m.alias || m.name).length << 1 == 2)) { | ||
DESERIALIZE += " else {\n"; | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key in JSON object \'" + String.fromCharCode(load<u16>(srcStart)) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
DESERIALIZE += indent + " }\n"; | ||
} else { | ||
DESERIALIZE += " else {\n"; | ||
if (isString(members[0].type)) DESERIALIZE += indent + " srcStart += 4;\n"; | ||
else if (!complex) DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " break;\n"; | ||
DESERIALIZE += indent + " }\n"; | ||
} | ||
@@ -546,3 +567,3 @@ }; | ||
let mbElse = " "; | ||
if (sortedMembers.string.length) { | ||
if (!STRICT || sortedMembers.string.length) { | ||
// generateGroups(sortedMembers.string, generateComparisions) | ||
@@ -556,3 +577,3 @@ DESERIALIZE += mbElse + "if (code == 34) {\n"; | ||
// DESERIALIZE += " console.log(JSON.Util.ptrToStr(keyStart,keyEnd) + \" = \" + load<u16>(keyStart).toString() + \" val \" + JSON.Util.ptrToStr(lastIndex, srcStart));\n"; | ||
generateGroups(sortedMembers.string, generateComparisions); | ||
generateGroups(sortedMembers.string, generateComparisions, "string"); | ||
DESERIALIZE += " }\n"; // Close break char check | ||
@@ -565,3 +586,3 @@ DESERIALIZE += " srcStart += 2;\n"; | ||
if (sortedMembers.number.length) { | ||
if (!STRICT || sortedMembers.number.length) { | ||
DESERIALIZE += mbElse + "if (code - 48 <= 9 || code == 45) {\n"; | ||
@@ -575,3 +596,3 @@ DESERIALIZE += " lastIndex = srcStart;\n"; | ||
generateGroups(sortedMembers.number, generateComparisions); | ||
generateGroups(sortedMembers.number, generateComparisions, "number"); | ||
DESERIALIZE += " }\n"; // Close break char check | ||
@@ -584,3 +605,3 @@ DESERIALIZE += " srcStart += 2;\n"; | ||
if (sortedMembers.object.length) { | ||
if (!STRICT || sortedMembers.object.length) { | ||
DESERIALIZE += mbElse + "if (code == 123) {\n"; | ||
@@ -600,3 +621,3 @@ DESERIALIZE += " lastIndex = srcStart;\n"; | ||
indent = " "; | ||
generateGroups(sortedMembers.object, generateComparisions); | ||
generateGroups(sortedMembers.object, generateComparisions, "object"); | ||
indent = ""; | ||
@@ -611,3 +632,3 @@ | ||
} | ||
if (sortedMembers.array.length) { | ||
if (!STRICT || sortedMembers.array.length) { | ||
DESERIALIZE += mbElse + "if (code == 91) {\n"; | ||
@@ -628,3 +649,3 @@ DESERIALIZE += " lastIndex = srcStart;\n"; | ||
indent = " "; | ||
generateGroups(sortedMembers.array, generateComparisions); | ||
generateGroups(sortedMembers.array, generateComparisions, "array"); | ||
indent = ""; | ||
@@ -640,37 +661,30 @@ | ||
if (sortedMembers.boolean.length) { | ||
if (!STRICT || sortedMembers.boolean.length) { | ||
// TRUE | ||
DESERIALIZE += mbElse + "if (code == 116) {\n"; | ||
DESERIALIZE += " if (load<u64>(srcStart) == 28429475166421108) {\n"; | ||
DESERIALIZE += " srcStart += 8;\n"; | ||
generateGroups( | ||
sortedMembers.boolean, | ||
(group) => { | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 2)) { | ||
DESERIALIZE += " const code16 = load<u16>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 4)) { | ||
DESERIALIZE += " const code32 = load<u32>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 6)) { | ||
DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 8)) { | ||
DESERIALIZE += " const code64 = load<u64>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 > 8)) { | ||
DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " "); | ||
} | ||
generateGroups(sortedMembers.boolean, (group) => { | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 2)) { | ||
DESERIALIZE += " const code16 = load<u16>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 4)) { | ||
DESERIALIZE += " const code32 = load<u32>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 6)) { | ||
DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 8)) { | ||
DESERIALIZE += " const code64 = load<u64>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 > 8)) { | ||
DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " "); | ||
} | ||
const firstMemberName = group[0].alias || group[0].name; | ||
DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n"; | ||
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " break;\n"; | ||
DESERIALIZE += indent + " }"; | ||
for (let i = 1; i < group.length; i++) { | ||
const member = group[i]; | ||
const memberName = member.alias || member.name; | ||
DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n"; | ||
DESERIALIZE += indent + " store<" + member.type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(member.name) + "));\n"; | ||
const firstMemberName = group[0].alias || group[0].name; | ||
DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n"; | ||
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
@@ -680,46 +694,64 @@ DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " }"; | ||
} | ||
if (STRICT) { | ||
DESERIALIZE += " else {\n"; | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key in JSON object \'" + String.fromCharCode(load<u16>(srcStart)) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
DESERIALIZE += indent + " }\n"; | ||
} | ||
}); | ||
for (let i = 1; i < group.length; i++) { | ||
const member = group[i]; | ||
const memberName = member.alias || member.name; | ||
DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n"; | ||
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), true, offsetof<this>(" + JSON.stringify(member.name) + "));\n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " break;\n"; | ||
DESERIALIZE += indent + " }"; | ||
} | ||
if (STRICT) { | ||
DESERIALIZE += " else {\n"; | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
DESERIALIZE += indent + " }\n"; | ||
} else { | ||
DESERIALIZE += " else { \n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " break;\n"; | ||
DESERIALIZE += indent + " }\n"; | ||
} | ||
}, | ||
"boolean", | ||
); | ||
DESERIALIZE += " }"; // Close first char check | ||
DESERIALIZE += " else {\n"; | ||
DESERIALIZE += " throw new Error(\"Expected to find 'true' but found '\" + JSON.Util.ptrToStr(lastIndex, srcStart) + \"' instead at position \" + (srcEnd - srcStart).toString());\n"; | ||
DESERIALIZE += " }"; // Close error check | ||
DESERIALIZE += "\n }"; // Close first char check | ||
mbElse = " else "; | ||
DESERIALIZE += " else if (load<u64>(srcStart, 2) == 28429466576093281) {\n"; | ||
DESERIALIZE += " srcStart += 10;\n"; | ||
generateGroups(sortedMembers.boolean, (group) => { | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 2)) { | ||
DESERIALIZE += " const code16 = load<u16>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 4)) { | ||
DESERIALIZE += " const code32 = load<u32>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 6)) { | ||
DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 8)) { | ||
DESERIALIZE += " const code64 = load<u64>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 > 8)) { | ||
DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " "); | ||
} | ||
const firstMemberName = group[0].alias || group[0].name; | ||
// FALSE | ||
DESERIALIZE += mbElse + "if (code == 102) {\n"; | ||
DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n"; | ||
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " break;\n"; | ||
DESERIALIZE += indent + " }"; | ||
DESERIALIZE += " if (load<u64>(srcStart, 2) == 28429466576093281) {\n"; | ||
DESERIALIZE += " srcStart += 10;\n"; | ||
generateGroups( | ||
sortedMembers.boolean, | ||
(group) => { | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 2)) { | ||
DESERIALIZE += " const code16 = load<u16>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 4)) { | ||
DESERIALIZE += " const code32 = load<u32>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 6)) { | ||
DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 8)) { | ||
DESERIALIZE += " const code64 = load<u64>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 > 8)) { | ||
DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " "); | ||
} | ||
for (let i = 1; i < group.length; i++) { | ||
const member = group[i]; | ||
const memberName = member.alias || member.name; | ||
DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n"; | ||
DESERIALIZE += indent + " store<" + member.type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(member.name) + "));\n"; | ||
const firstMemberName = group[0].alias || group[0].name; | ||
DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n"; | ||
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
@@ -729,15 +761,39 @@ DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " }"; | ||
} | ||
if (STRICT) { | ||
DESERIALIZE += " else {\n"; | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key in JSON object \'" + String.fromCharCode(load<u16>(srcStart)) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
DESERIALIZE += indent + " }\n"; | ||
} | ||
}); | ||
DESERIALIZE += " }\n"; // Close first char check | ||
DESERIALIZE += " }"; // Close first char check | ||
for (let i = 1; i < group.length; i++) { | ||
const member = group[i]; | ||
const memberName = member.alias || member.name; | ||
DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n"; | ||
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), false, offsetof<this>(" + JSON.stringify(member.name) + "));\n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " break;\n"; | ||
DESERIALIZE += indent + " }"; | ||
} | ||
if (STRICT) { | ||
DESERIALIZE += " else {\n"; | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
DESERIALIZE += indent + " }\n"; | ||
} else { | ||
DESERIALIZE += " else { \n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " break;\n"; | ||
DESERIALIZE += indent + " }\n"; | ||
} | ||
}, | ||
"boolean", | ||
); | ||
DESERIALIZE += " }"; // Close first char check | ||
DESERIALIZE += " else {\n"; | ||
DESERIALIZE += " throw new Error(\"Expected to find 'false' but found '\" + JSON.Util.ptrToStr(lastIndex, srcStart) + \"' instead at position \" + (srcEnd - srcStart).toString());\n"; | ||
DESERIALIZE += " }"; // Close error check | ||
DESERIALIZE += "\n }"; // Close first char check | ||
mbElse = " else "; | ||
} | ||
if (sortedMembers.null.length) { | ||
if (!STRICT || sortedMembers.null.length) { | ||
DESERIALIZE += mbElse + "if (code == 110) {\n"; | ||
@@ -747,31 +803,23 @@ | ||
DESERIALIZE += " srcStart += 8;\n"; | ||
generateGroups(sortedMembers.null, (group) => { | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 2)) { | ||
DESERIALIZE += " const code16 = load<u16>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 4)) { | ||
DESERIALIZE += " const code32 = load<u32>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 6)) { | ||
DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 8)) { | ||
DESERIALIZE += " const code64 = load<u64>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 > 8)) { | ||
DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " "); | ||
} | ||
generateGroups( | ||
sortedMembers.null, | ||
(group) => { | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 2)) { | ||
DESERIALIZE += " const code16 = load<u16>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 4)) { | ||
DESERIALIZE += " const code32 = load<u32>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 6)) { | ||
DESERIALIZE += " const code48 = load<u64>(keyStart) & 0x0000FFFFFFFFFFFF;\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 == 8)) { | ||
DESERIALIZE += " const code64 = load<u64>(keyStart);\n"; | ||
} | ||
if (group.some((m) => (m.alias || m.name).length << 1 > 8)) { | ||
DESERIALIZE += toMemCDecl(Math.max(...group.map((m) => (m.alias || m.name).length << 1)), " "); | ||
} | ||
const firstMemberName = group[0].alias || group[0].name; | ||
DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n"; | ||
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), null, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " break;\n"; | ||
DESERIALIZE += indent + " }"; | ||
for (let i = 1; i < group.length; i++) { | ||
const member = group[i]; | ||
const memberName = member.alias || member.name; | ||
DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n"; | ||
const firstMemberName = group[0].alias || group[0].name; | ||
DESERIALIZE += indent + " if (" + getComparision(firstMemberName) + ") { // " + firstMemberName + "\n"; | ||
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), null, offsetof<this>(" + JSON.stringify(group[0].name) + "));\n"; | ||
@@ -782,11 +830,29 @@ DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " }"; | ||
} | ||
if (STRICT) { | ||
DESERIALIZE += " else {\n"; | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key in JSON object \'" + String.fromCharCode(load<u16>(srcStart)) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
DESERIALIZE += indent + " }\n"; | ||
} | ||
}, true); | ||
for (let i = 1; i < group.length; i++) { | ||
const member = group[i]; | ||
const memberName = member.alias || member.name; | ||
DESERIALIZE += indent + " else if (" + getComparision(memberName) + ") { // " + memberName + "\n"; | ||
DESERIALIZE += indent + " store<" + group[0].type + ">(changetype<usize>(out), null, offsetof<this>(" + JSON.stringify(member.name) + "));\n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " break;\n"; | ||
DESERIALIZE += indent + " }"; | ||
} | ||
if (STRICT) { | ||
DESERIALIZE += " else {\n"; | ||
DESERIALIZE += indent + ' throw new Error("Unexpected key value pair in JSON object \'" + JSON.Util.ptrToStr(keyStart, keyEnd) + ":" + JSON.Util.ptrToStr(lastIndex, srcStart) + "\' at position " + (srcEnd - srcStart).toString());\n'; | ||
DESERIALIZE += indent + " }\n"; | ||
} else { | ||
DESERIALIZE += " else { \n"; | ||
DESERIALIZE += indent + " srcStart += 2;\n"; | ||
DESERIALIZE += indent + " keyStart = 0;\n"; | ||
DESERIALIZE += indent + " break;\n"; | ||
DESERIALIZE += indent + " }\n"; | ||
} | ||
}, | ||
"null", | ||
); | ||
DESERIALIZE += " }"; // Close first char check | ||
@@ -800,2 +866,3 @@ DESERIALIZE += "\n }"; // Close first char check | ||
DESERIALIZE += " srcStart += 2;\n"; | ||
DESERIALIZE += " keyStart = 0;\n"; | ||
DESERIALIZE += "}\n"; | ||
@@ -1214,2 +1281,2 @@ DESERIALIZE += "\n }\n"; // Close value portion | ||
} | ||
} | ||
} |
@@ -7,3 +7,3 @@ import { ClassDeclaration, Expression, FieldDeclaration } from "assemblyscript/dist/assemblyscript.js"; | ||
Raw, | ||
Custom | ||
Custom, | ||
} | ||
@@ -10,0 +10,0 @@ |
@@ -58,7 +58,3 @@ // Taken from https://github.com/as-pect/visitor-as/blob/master/src/simpleParser.ts | ||
export function replaceRef( | ||
node: Node, | ||
replacement: Node | Node[], | ||
ref: Node | Node[] | null, | ||
): void { | ||
export function replaceRef(node: Node, replacement: Node | Node[], ref: Node | Node[] | null): void { | ||
if (!node || !ref) return; | ||
@@ -81,4 +77,3 @@ const nodeExpr = stripExpr(node); | ||
if (stripExpr(current[i]) === nodeExpr) { | ||
if (Array.isArray(replacement)) | ||
current.splice(i, 1, ...replacement); | ||
if (Array.isArray(replacement)) current.splice(i, 1, ...replacement); | ||
else current.splice(i, 1, replacement); | ||
@@ -96,13 +91,7 @@ return; | ||
export function cloneNode( | ||
input: Node | Node[] | null, | ||
seen = new WeakMap(), | ||
path = "", | ||
): Node | Node[] | null { | ||
export function cloneNode(input: Node | Node[] | null, seen = new WeakMap(), path = ""): Node | Node[] | null { | ||
if (input === null || typeof input !== "object") return input; | ||
if (Array.isArray(input)) { | ||
return input.map((item, index) => | ||
cloneNode(item, seen, `${path}[${index}]`), | ||
) as Node | Node[] | null; | ||
return input.map((item, index) => cloneNode(item, seen, `${path}[${index}]`)) as Node | Node[] | null; | ||
} | ||
@@ -136,2 +125,2 @@ | ||
return node; | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
595275
1.7%10773
-0.01%