@latticexyz/utils 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +187 -0
- package/README.md +3 -0
- package/jest.config.js +5 -0
- package/package.json +44 -0
- package/rollup.config.js +16 -0
- package/src/CoordMap.spec.ts +57 -0
- package/src/CoordMap.ts +106 -0
- package/src/area.ts +15 -0
- package/src/arrays.ts +19 -0
- package/src/console.ts +62 -0
- package/src/cubic.spec.ts +14 -0
- package/src/cubic.ts +109 -0
- package/src/deferred.ts +14 -0
- package/src/enums.ts +13 -0
- package/src/eth.ts +42 -0
- package/src/guards.ts +10 -0
- package/src/hash.ts +11 -0
- package/src/index.ts +34 -0
- package/src/iterable.spec.ts +56 -0
- package/src/iterable.ts +59 -0
- package/src/mobx.ts +26 -0
- package/src/objects.ts +16 -0
- package/src/pack.spec.ts +37 -0
- package/src/pack.ts +61 -0
- package/src/promise.ts +45 -0
- package/src/proxy.spec.ts +186 -0
- package/src/proxy.ts +101 -0
- package/src/random.ts +17 -0
- package/src/rx.spec.ts +45 -0
- package/src/rx.ts +124 -0
- package/src/sleep.ts +3 -0
- package/src/types.ts +48 -0
- package/src/uuid.ts +70 -0
- package/src/worker.ts +16 -0
- package/tsconfig.json +102 -0
- package/typedoc.json +9 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
|
+
|
|
6
|
+
# [0.9.0](https://github.com/latticexyz/mud/compare/v0.8.1...v0.9.0) (2022-09-13)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
- **network:** align hex entity id formatting ([#140](https://github.com/latticexyz/mud/issues/140)) ([93b1bd6](https://github.com/latticexyz/mud/commit/93b1bd6688780dc185a1c7e353954e2c5c85f648))
|
|
11
|
+
|
|
12
|
+
## [0.8.1](https://github.com/latticexyz/mud/compare/v0.8.0...v0.8.1) (2022-08-22)
|
|
13
|
+
|
|
14
|
+
**Note:** Version bump only for package @latticexyz/utils
|
|
15
|
+
|
|
16
|
+
# [0.8.0](https://github.com/latticexyz/mud/compare/v0.7.0...v0.8.0) (2022-08-22)
|
|
17
|
+
|
|
18
|
+
### Features
|
|
19
|
+
|
|
20
|
+
- add mud.dev ([#133](https://github.com/latticexyz/mud/issues/133)) ([302588c](https://github.com/latticexyz/mud/commit/302588cbbab2803396b894bc006d13e6ac943da9))
|
|
21
|
+
|
|
22
|
+
# [0.7.0](https://github.com/latticexyz/mud/compare/v0.6.0...v0.7.0) (2022-08-19)
|
|
23
|
+
|
|
24
|
+
**Note:** Version bump only for package @latticexyz/utils
|
|
25
|
+
|
|
26
|
+
# [0.6.0](https://github.com/latticexyz/mud/compare/v0.5.1...v0.6.0) (2022-08-15)
|
|
27
|
+
|
|
28
|
+
### Code Refactoring
|
|
29
|
+
|
|
30
|
+
- sync worker (+ integrated snapshot service) ([#125](https://github.com/latticexyz/mud/issues/125)) ([6173b59](https://github.com/latticexyz/mud/commit/6173b596713b0dad73d14288ece3ac66ca3972d3))
|
|
31
|
+
|
|
32
|
+
### BREAKING CHANGES
|
|
33
|
+
|
|
34
|
+
- sync worker update stream returns component id instead of component key
|
|
35
|
+
|
|
36
|
+
- test(network): add tests for sync utils and SyncWorker logic
|
|
37
|
+
|
|
38
|
+
- chore: remove logs and improve comments
|
|
39
|
+
|
|
40
|
+
- chore: add logs
|
|
41
|
+
|
|
42
|
+
Co-authored-by: andrii dobroshynski <24281657+andriidski@users.noreply.github.com>
|
|
43
|
+
|
|
44
|
+
## [0.5.1](https://github.com/latticexyz/mud/compare/v0.5.0...v0.5.1) (2022-08-05)
|
|
45
|
+
|
|
46
|
+
**Note:** Version bump only for package @latticexyz/utils
|
|
47
|
+
|
|
48
|
+
# [0.5.0](https://github.com/latticexyz/mud/compare/v0.4.3...v0.5.0) (2022-08-05)
|
|
49
|
+
|
|
50
|
+
### Bug Fixes
|
|
51
|
+
|
|
52
|
+
- optimism, cancel action if gas check fails, add noise utils, fix ecs-browser entry point ([#119](https://github.com/latticexyz/mud/issues/119)) ([f35d3c3](https://github.com/latticexyz/mud/commit/f35d3c3cc7fc9385a215dfda6762a2a825c9fd6d))
|
|
53
|
+
|
|
54
|
+
### Features
|
|
55
|
+
|
|
56
|
+
- logging library with support for topics/filters ([#123](https://github.com/latticexyz/mud/issues/123)) ([4eac3c6](https://github.com/latticexyz/mud/commit/4eac3c6f45cf300c683397d68e405001d31d8dda))
|
|
57
|
+
|
|
58
|
+
## [0.4.3](https://github.com/latticexyz/mud/compare/v0.4.2...v0.4.3) (2022-07-30)
|
|
59
|
+
|
|
60
|
+
**Note:** Version bump only for package @latticexyz/utils
|
|
61
|
+
|
|
62
|
+
## [0.4.2](https://github.com/latticexyz/mud/compare/v0.4.1...v0.4.2) (2022-07-29)
|
|
63
|
+
|
|
64
|
+
**Note:** Version bump only for package @latticexyz/utils
|
|
65
|
+
|
|
66
|
+
## [0.4.1](https://github.com/latticexyz/mud/compare/v0.4.0...v0.4.1) (2022-07-29)
|
|
67
|
+
|
|
68
|
+
**Note:** Version bump only for package @latticexyz/utils
|
|
69
|
+
|
|
70
|
+
# [0.4.0](https://github.com/latticexyz/mud/compare/v0.3.2...v0.4.0) (2022-07-29)
|
|
71
|
+
|
|
72
|
+
### Bug Fixes
|
|
73
|
+
|
|
74
|
+
- **cli:** extract encoded arguments from signature ([#116](https://github.com/latticexyz/mud/issues/116)) ([f630319](https://github.com/latticexyz/mud/commit/f6303194c5d7147a64542e43669fddebf3abad1a))
|
|
75
|
+
|
|
76
|
+
### Features
|
|
77
|
+
|
|
78
|
+
- add 3d components ([d230339](https://github.com/latticexyz/mud/commit/d230339bdf3fbfaf4596de759a25fb616a7ab572))
|
|
79
|
+
|
|
80
|
+
## [0.3.2](https://github.com/latticexyz/mud/compare/v0.3.1...v0.3.2) (2022-07-26)
|
|
81
|
+
|
|
82
|
+
**Note:** Version bump only for package @latticexyz/utils
|
|
83
|
+
|
|
84
|
+
## [0.3.1](https://github.com/latticexyz/mud/compare/v0.3.0...v0.3.1) (2022-07-26)
|
|
85
|
+
|
|
86
|
+
**Note:** Version bump only for package @latticexyz/utils
|
|
87
|
+
|
|
88
|
+
# [0.3.0](https://github.com/latticexyz/mud/compare/v0.2.0...v0.3.0) (2022-07-26)
|
|
89
|
+
|
|
90
|
+
### Features
|
|
91
|
+
|
|
92
|
+
- mudwar prototype (nyc sprint 2) ([#59](https://github.com/latticexyz/mud/issues/59)) ([a3db20e](https://github.com/latticexyz/mud/commit/a3db20e14c641b8b456775ee191eca6f016d47f5)), closes [#58](https://github.com/latticexyz/mud/issues/58) [#61](https://github.com/latticexyz/mud/issues/61) [#64](https://github.com/latticexyz/mud/issues/64) [#62](https://github.com/latticexyz/mud/issues/62) [#66](https://github.com/latticexyz/mud/issues/66) [#69](https://github.com/latticexyz/mud/issues/69) [#72](https://github.com/latticexyz/mud/issues/72) [#73](https://github.com/latticexyz/mud/issues/73) [#74](https://github.com/latticexyz/mud/issues/74) [#76](https://github.com/latticexyz/mud/issues/76) [#75](https://github.com/latticexyz/mud/issues/75) [#77](https://github.com/latticexyz/mud/issues/77) [#78](https://github.com/latticexyz/mud/issues/78) [#79](https://github.com/latticexyz/mud/issues/79) [#80](https://github.com/latticexyz/mud/issues/80) [#82](https://github.com/latticexyz/mud/issues/82) [#86](https://github.com/latticexyz/mud/issues/86) [#83](https://github.com/latticexyz/mud/issues/83) [#81](https://github.com/latticexyz/mud/issues/81) [#85](https://github.com/latticexyz/mud/issues/85) [#84](https://github.com/latticexyz/mud/issues/84) [#87](https://github.com/latticexyz/mud/issues/87) [#91](https://github.com/latticexyz/mud/issues/91) [#88](https://github.com/latticexyz/mud/issues/88) [#90](https://github.com/latticexyz/mud/issues/90) [#92](https://github.com/latticexyz/mud/issues/92) [#93](https://github.com/latticexyz/mud/issues/93) [#89](https://github.com/latticexyz/mud/issues/89) [#94](https://github.com/latticexyz/mud/issues/94) [#95](https://github.com/latticexyz/mud/issues/95) [#98](https://github.com/latticexyz/mud/issues/98) [#100](https://github.com/latticexyz/mud/issues/100) [#97](https://github.com/latticexyz/mud/issues/97) [#101](https://github.com/latticexyz/mud/issues/101) [#105](https://github.com/latticexyz/mud/issues/105) [#106](https://github.com/latticexyz/mud/issues/106)
|
|
93
|
+
|
|
94
|
+
# [0.2.0](https://github.com/latticexyz/mud/compare/v0.1.8...v0.2.0) (2022-07-05)
|
|
95
|
+
|
|
96
|
+
### Features
|
|
97
|
+
|
|
98
|
+
- add webworker architecture for contract/client sync, add cache webworker ([#10](https://github.com/latticexyz/mud/issues/10)) ([4ef9f90](https://github.com/latticexyz/mud/commit/4ef9f909d1d3c10f6bea888b2c32b1d1df04185a)), closes [#14](https://github.com/latticexyz/mud/issues/14)
|
|
99
|
+
- on-chain maps (nyc sprint 1) ([#38](https://github.com/latticexyz/mud/issues/38)) ([089c46d](https://github.com/latticexyz/mud/commit/089c46d7c0e112d1670e3bcd01a35f08ee21d593)), closes [#17](https://github.com/latticexyz/mud/issues/17) [#20](https://github.com/latticexyz/mud/issues/20) [#18](https://github.com/latticexyz/mud/issues/18) [#25](https://github.com/latticexyz/mud/issues/25) [#26](https://github.com/latticexyz/mud/issues/26) [#27](https://github.com/latticexyz/mud/issues/27) [#28](https://github.com/latticexyz/mud/issues/28) [#29](https://github.com/latticexyz/mud/issues/29) [#30](https://github.com/latticexyz/mud/issues/30) [#31](https://github.com/latticexyz/mud/issues/31) [#33](https://github.com/latticexyz/mud/issues/33) [#32](https://github.com/latticexyz/mud/issues/32) [#34](https://github.com/latticexyz/mud/issues/34) [#35](https://github.com/latticexyz/mud/issues/35) [#36](https://github.com/latticexyz/mud/issues/36) [#37](https://github.com/latticexyz/mud/issues/37) [#39](https://github.com/latticexyz/mud/issues/39) [#40](https://github.com/latticexyz/mud/issues/40) [#41](https://github.com/latticexyz/mud/issues/41) [#42](https://github.com/latticexyz/mud/issues/42) [#43](https://github.com/latticexyz/mud/issues/43) [#44](https://github.com/latticexyz/mud/issues/44) [#45](https://github.com/latticexyz/mud/issues/45) [#46](https://github.com/latticexyz/mud/issues/46) [#48](https://github.com/latticexyz/mud/issues/48) [#49](https://github.com/latticexyz/mud/issues/49) [#50](https://github.com/latticexyz/mud/issues/50)
|
|
100
|
+
|
|
101
|
+
### BREAKING CHANGES
|
|
102
|
+
|
|
103
|
+
- Components have to implement a getSchema() function
|
|
104
|
+
|
|
105
|
+
- feat(network): make Sync worker return a stream of ECS events (prev contract events)
|
|
106
|
+
|
|
107
|
+
- feat(ri-contracts): integrate solecs change (add getSchema to components)
|
|
108
|
+
|
|
109
|
+
- feat(ri-client): integrate network package changes
|
|
110
|
+
|
|
111
|
+
- feat(network): store ECS state in cache
|
|
112
|
+
|
|
113
|
+
- feat(network): load state from cache
|
|
114
|
+
|
|
115
|
+
- feat(utils): add more utils for iterables
|
|
116
|
+
|
|
117
|
+
- refactor(network): clean up
|
|
118
|
+
|
|
119
|
+
- feat(network): generalize component value decoder function, add tests
|
|
120
|
+
|
|
121
|
+
- fix(network): make it possible to subscribe to ecsStream from sync worker multiple times
|
|
122
|
+
|
|
123
|
+
- fix(network): start sync from provided initial block number
|
|
124
|
+
|
|
125
|
+
- feat(network): move storing ecs to indexDB to its own Cache worker
|
|
126
|
+
|
|
127
|
+
- feat(network): create separate cache for every World contract address
|
|
128
|
+
|
|
129
|
+
- fix(network): fix issues discovered during live review
|
|
130
|
+
|
|
131
|
+
- chore: remove unused import
|
|
132
|
+
|
|
133
|
+
- Update packages/network/src/createBlockNumberStream.ts
|
|
134
|
+
|
|
135
|
+
Co-authored-by: ludens <ludens@lattice.xyz>
|
|
136
|
+
|
|
137
|
+
- feat(network): add clock syncInterval as config parameter
|
|
138
|
+
|
|
139
|
+
- feat(utils): emit values through componentToStream and observableToStream only if non-null
|
|
140
|
+
|
|
141
|
+
- feat(network): add chain id to cache id, disable loading from cache on hardhat
|
|
142
|
+
|
|
143
|
+
- fix(contracts): change Position and EntityType schema to int32/uint32 to fit in js number
|
|
144
|
+
|
|
145
|
+
- docs(client): fix typos in comments
|
|
146
|
+
|
|
147
|
+
- fix(network): fix tests
|
|
148
|
+
|
|
149
|
+
- fix(scripting): integrate new network package into ri scripting
|
|
150
|
+
|
|
151
|
+
- fix(network): fix sending multiple requests for component schema if many events get reduced
|
|
152
|
+
|
|
153
|
+
## [0.1.8](https://github.com/latticexyz/mud/compare/v0.1.7...v0.1.8) (2022-05-25)
|
|
154
|
+
|
|
155
|
+
**Note:** Version bump only for package @latticexyz/utils
|
|
156
|
+
|
|
157
|
+
## [0.1.7](https://github.com/latticexyz/mud/compare/v0.1.6...v0.1.7) (2022-05-25)
|
|
158
|
+
|
|
159
|
+
**Note:** Version bump only for package @latticexyz/utils
|
|
160
|
+
|
|
161
|
+
## [0.1.6](https://github.com/latticexyz/mud/compare/v0.1.5...v0.1.6) (2022-05-25)
|
|
162
|
+
|
|
163
|
+
**Note:** Version bump only for package @latticexyz/utils
|
|
164
|
+
|
|
165
|
+
## [0.1.4](https://github.com/latticexyz/mud/compare/v0.1.3...v0.1.4) (2022-05-24)
|
|
166
|
+
|
|
167
|
+
**Note:** Version bump only for package @latticexyz/utils
|
|
168
|
+
|
|
169
|
+
## [0.1.3](https://github.com/latticexyz/mud/compare/v0.1.2...v0.1.3) (2022-05-23)
|
|
170
|
+
|
|
171
|
+
**Note:** Version bump only for package @latticexyz/utils
|
|
172
|
+
|
|
173
|
+
## [0.1.2](https://github.com/latticexyz/mud/compare/v0.1.1...v0.1.2) (2022-05-23)
|
|
174
|
+
|
|
175
|
+
**Note:** Version bump only for package @latticexyz/utils
|
|
176
|
+
|
|
177
|
+
## [0.1.1](https://github.com/latticexyz/mud/compare/v0.1.0...v0.1.1) (2022-05-23)
|
|
178
|
+
|
|
179
|
+
**Note:** Version bump only for package @latticexyz/utils
|
|
180
|
+
|
|
181
|
+
# 0.1.0 (2022-05-23)
|
|
182
|
+
|
|
183
|
+
### Features
|
|
184
|
+
|
|
185
|
+
- **@mud/utils:** add @mud/utils package ([fc721cc](https://github.com/latticexyz/mud/commit/fc721cc564b20150c3b13883cb3edb773f48e312))
|
|
186
|
+
- **@mud/utils:** add keccak256 hash function that accepts string inputs ([ca1a4e0](https://github.com/latticexyz/mud/commit/ca1a4e0cc7452724e703a6530c2e56112c307b66))
|
|
187
|
+
- **@mud/utils:** add stretch rxjs operator to add a minimum delay between events in a rxjs stream ([3a1673f](https://github.com/latticexyz/mud/commit/3a1673f5fba548f94afd5580a7e32007a6edd57f))
|
package/README.md
ADDED
package/jest.config.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@latticexyz/utils",
|
|
3
|
+
"license": "MIT",
|
|
4
|
+
"version": "0.9.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/latticexyz/mud.git",
|
|
10
|
+
"directory": "packages/utils"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"lint": "eslint . --ext .ts",
|
|
14
|
+
"test": "jest",
|
|
15
|
+
"build": "rimraf dist && rollup -c rollup.config.js",
|
|
16
|
+
"link": "yarn link",
|
|
17
|
+
"docs": "typedoc src"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@rollup/plugin-node-resolve": "^13.1.3",
|
|
21
|
+
"@rollup/plugin-typescript": "^8.3.1",
|
|
22
|
+
"@types/jest": "^27.4.1",
|
|
23
|
+
"ethers": "^5.6.6",
|
|
24
|
+
"jest": "^27.5.1",
|
|
25
|
+
"mobx": "^6.5.0",
|
|
26
|
+
"proxy-deep": "^3.1.1",
|
|
27
|
+
"rimraf": "^3.0.2",
|
|
28
|
+
"rollup": "^2.69.0",
|
|
29
|
+
"rollup-plugin-commonjs": "^10.1.0",
|
|
30
|
+
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
31
|
+
"rxjs": "^7.5.5",
|
|
32
|
+
"ts-jest": "^27.1.3",
|
|
33
|
+
"tslib": "^2.3.1",
|
|
34
|
+
"typedoc": "^0.23.10",
|
|
35
|
+
"typescript": "^4.5.5"
|
|
36
|
+
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"ethers": "^5.6.6",
|
|
39
|
+
"mobx": "^6.5.0",
|
|
40
|
+
"proxy-deep": "^3.1.1",
|
|
41
|
+
"rxjs": "^7.5.5"
|
|
42
|
+
},
|
|
43
|
+
"gitHead": "40718ea9955e61196942d040189adec464500446"
|
|
44
|
+
}
|
package/rollup.config.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import typescript from "@rollup/plugin-typescript";
|
|
2
|
+
import { nodeResolve } from "@rollup/plugin-node-resolve";
|
|
3
|
+
import commonjs from "rollup-plugin-commonjs";
|
|
4
|
+
import peerDepsExternal from "rollup-plugin-peer-deps-external";
|
|
5
|
+
|
|
6
|
+
import { defineConfig } from "rollup";
|
|
7
|
+
|
|
8
|
+
export default defineConfig({
|
|
9
|
+
input: "./src/index.ts",
|
|
10
|
+
treeshake: true,
|
|
11
|
+
output: {
|
|
12
|
+
dir: "dist",
|
|
13
|
+
sourcemap: true,
|
|
14
|
+
},
|
|
15
|
+
plugins: [nodeResolve(), typescript(), commonjs(), peerDepsExternal()],
|
|
16
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { coordToKey, keyToCoord } from "./CoordMap";
|
|
2
|
+
|
|
3
|
+
describe("CoordMap", () => {
|
|
4
|
+
describe("coordToKey", () => {
|
|
5
|
+
it("should be the inverse of keyToCoord", () => {
|
|
6
|
+
const MAX = 2 ** 15 - 1;
|
|
7
|
+
const coords = [
|
|
8
|
+
{ x: 1, y: 2 },
|
|
9
|
+
{ x: -1, y: 2 },
|
|
10
|
+
{ x: 1, y: -2 },
|
|
11
|
+
{ x: 0, y: 0 },
|
|
12
|
+
{ x: -1, y: -2 },
|
|
13
|
+
{ x: MAX, y: MAX },
|
|
14
|
+
{ x: -1 * MAX, y: MAX },
|
|
15
|
+
{ x: MAX, y: -1 * MAX },
|
|
16
|
+
{ x: -1 * MAX, y: -1 * MAX },
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
for (const coord of coords) {
|
|
20
|
+
const key = coordToKey(coord);
|
|
21
|
+
expect(keyToCoord(key)).toEqual(coord);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe("keyToCoord", () => {
|
|
27
|
+
it("should be the inverse of coordToKey", () => {
|
|
28
|
+
const keys = [
|
|
29
|
+
"11111111111111110000000000000000",
|
|
30
|
+
"11011101110111011000101001001000",
|
|
31
|
+
"01101101101110110001010101111001",
|
|
32
|
+
"11010101111011010010010010001001",
|
|
33
|
+
"00111111111111110111000001001100",
|
|
34
|
+
"01101110001111010110010010001001",
|
|
35
|
+
"10101110011011010010010001010101",
|
|
36
|
+
"01011011101011010101100100101000",
|
|
37
|
+
"11011110111101111000010000100011",
|
|
38
|
+
"10110111011011010101101010001001",
|
|
39
|
+
"00110111011101110001000100010000",
|
|
40
|
+
"10110101101101010001001010001001",
|
|
41
|
+
"01100011010101111010010100110010",
|
|
42
|
+
"11111111111111111111111111111111",
|
|
43
|
+
"00000000000000000000000000000000",
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
for (const key of keys) {
|
|
47
|
+
const numKey = parseInt(key, 2) >> 0;
|
|
48
|
+
const coord = keyToCoord(numKey);
|
|
49
|
+
expect(coordToKey(coord)).toEqual(numKey);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("should work with {x: 0, y: 0}", () => {
|
|
54
|
+
expect(keyToCoord(0)).toEqual({ x: 0, y: 0 });
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
});
|
package/src/CoordMap.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { Coord } from "./types";
|
|
2
|
+
import { transformIterator } from "./iterable";
|
|
3
|
+
|
|
4
|
+
const LOWER_HALF_MASK = 2 ** 16 - 1;
|
|
5
|
+
const MAX_SUPPORTED = 2 ** 15 - 1;
|
|
6
|
+
|
|
7
|
+
export function subtract(from: CoordMap<boolean>, subtract: CoordMap<boolean>): CoordMap<boolean> {
|
|
8
|
+
const result = new CoordMap<boolean>();
|
|
9
|
+
|
|
10
|
+
for (const coord of from.coords()) {
|
|
11
|
+
if (subtract.get(coord)) continue;
|
|
12
|
+
result.set(coord, true);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function coordToKey(coord: Coord) {
|
|
19
|
+
const key = (coord.x << 16) | (coord.y & LOWER_HALF_MASK);
|
|
20
|
+
return key;
|
|
21
|
+
|
|
22
|
+
// Old version using strings:
|
|
23
|
+
// return `${coord.x}/${coord.y}`;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function keyToCoord(key: number): Coord {
|
|
27
|
+
const x = key >> 16;
|
|
28
|
+
const y = (key << 16) >> 16;
|
|
29
|
+
return { x, y };
|
|
30
|
+
|
|
31
|
+
// Old version using strings:
|
|
32
|
+
// const fragments = key.split("/");
|
|
33
|
+
// return { x: Number(fragments[0]), y: Number(fragments[1]) };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export class CoordMap<T> {
|
|
37
|
+
map: Map<number, T>;
|
|
38
|
+
defaultValue?: T;
|
|
39
|
+
|
|
40
|
+
constructor(props?: { defaultValue?: T }) {
|
|
41
|
+
this.map = new Map<number, T>();
|
|
42
|
+
this.defaultValue = props?.defaultValue;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
static from<T>(coordMapLike: { map: Map<number, T>; defaultValue?: T }): CoordMap<T> {
|
|
46
|
+
const coordMap = new CoordMap<T>();
|
|
47
|
+
coordMap.map = coordMapLike.map;
|
|
48
|
+
coordMap.defaultValue = coordMapLike.defaultValue;
|
|
49
|
+
return coordMap;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
set(coord: Coord, value: T) {
|
|
53
|
+
if (
|
|
54
|
+
coord.x > MAX_SUPPORTED ||
|
|
55
|
+
coord.x < -1 * MAX_SUPPORTED ||
|
|
56
|
+
coord.y > MAX_SUPPORTED ||
|
|
57
|
+
coord.y < -1 * MAX_SUPPORTED
|
|
58
|
+
) {
|
|
59
|
+
throw new Error(`CoordMap only supports coords up to ${MAX_SUPPORTED}`);
|
|
60
|
+
}
|
|
61
|
+
return this.map.set(coordToKey(coord), value);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
get(coord: Coord) {
|
|
65
|
+
return this.map.get(coordToKey(coord)) ?? this.defaultValue;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
keys() {
|
|
69
|
+
return this.map.keys();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
coords(): IterableIterator<Coord> {
|
|
73
|
+
return transformIterator(this.map.keys(), (key) => keyToCoord(key));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
entries() {
|
|
77
|
+
return this.map.entries();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
toArray(): [Coord, T][] {
|
|
81
|
+
const entries = Array.from(this.map.entries());
|
|
82
|
+
return entries.map(([key, value]) => [keyToCoord(key), value]);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
values() {
|
|
86
|
+
return this.map.values();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
delete(coord: Coord) {
|
|
90
|
+
return this.map.delete(coordToKey(coord));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
has(coord: Coord): boolean {
|
|
94
|
+
return this.map.has(coordToKey(coord));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
clear() {
|
|
98
|
+
for (const key of this.map.keys()) {
|
|
99
|
+
this.map.delete(key);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
get size(): number {
|
|
104
|
+
return this.map.size;
|
|
105
|
+
}
|
|
106
|
+
}
|
package/src/area.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Area, Coord } from "./types";
|
|
2
|
+
|
|
3
|
+
export function areaContains(area: Area, coord: Coord) {
|
|
4
|
+
return coord.x >= area.x && coord.y >= area.y && coord.x < area.x + area.width && coord.y < area.y + area.height;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function coordsOf(area: Area) {
|
|
8
|
+
const coords: Coord[] = [];
|
|
9
|
+
for (let dx = 0; dx < area.width; dx++) {
|
|
10
|
+
for (let dy = 0; dy < area.height; dy++) {
|
|
11
|
+
coords.push({ x: area.x + dx, y: area.y + dy });
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return coords;
|
|
15
|
+
}
|
package/src/arrays.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript type guard to assert the type of a non-empty array
|
|
3
|
+
* @param array Any array to check for non-emptiness
|
|
4
|
+
* @returns True if the empty is non-empty, else false. TypeScript accepts the array as non-empty after the assertion.
|
|
5
|
+
*/
|
|
6
|
+
export function isNotEmpty<T>(array: T[]): array is [T, ...T[]] {
|
|
7
|
+
if (array.length === 0) return false;
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Filters undefined values from an array and lets TypeScript know the resulting array
|
|
13
|
+
* does not have undefined values
|
|
14
|
+
* @param array Array potentially including undefined values
|
|
15
|
+
* @returns Array without undefined values
|
|
16
|
+
*/
|
|
17
|
+
export function filterNullishValues<T>(array: (T | undefined)[]): T[] {
|
|
18
|
+
return array.filter((value) => value != null) as T[];
|
|
19
|
+
}
|
package/src/console.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const TOPICS_KEY = "mud-logger-topics";
|
|
2
|
+
|
|
3
|
+
export function enableLogger() {
|
|
4
|
+
const windowConsole = window.console;
|
|
5
|
+
let filtersActive = Boolean(localStorage.getItem(TOPICS_KEY));
|
|
6
|
+
|
|
7
|
+
const topicsString = localStorage.getItem(TOPICS_KEY);
|
|
8
|
+
let topics: string[] = topicsString ? JSON.parse(topicsString) : [];
|
|
9
|
+
|
|
10
|
+
function log(...logs: string[]) {
|
|
11
|
+
if (filtersActive) return;
|
|
12
|
+
windowConsole.log(...logs);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function logWithTopic(topic: string, ...logs: string[]) {
|
|
16
|
+
if (!filtersActive || topics.includes(topic)) {
|
|
17
|
+
windowConsole.log(`--- BETTER CONSOLE / TOPIC ${topic} ---`);
|
|
18
|
+
windowConsole.log(...logs);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function enableFilters() {
|
|
23
|
+
localStorage.setItem(TOPICS_KEY, JSON.stringify([]));
|
|
24
|
+
filtersActive = true;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function disableFilters() {
|
|
28
|
+
localStorage.removeItem(TOPICS_KEY);
|
|
29
|
+
filtersActive = false;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function addTopic(topic: string) {
|
|
33
|
+
topics.push(topic);
|
|
34
|
+
localStorage.setItem(TOPICS_KEY, JSON.stringify(topics));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function removeTopic(topic: string) {
|
|
38
|
+
topics = topics.filter((t) => t !== topic);
|
|
39
|
+
localStorage.setItem(TOPICS_KEY, JSON.stringify(topics));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function resetTopics() {
|
|
43
|
+
topics = [];
|
|
44
|
+
localStorage.setItem(TOPICS_KEY, JSON.stringify(topics));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const logger = {
|
|
48
|
+
...windowConsole,
|
|
49
|
+
log,
|
|
50
|
+
logWithTopic,
|
|
51
|
+
enableFilters,
|
|
52
|
+
disableFilters,
|
|
53
|
+
addTopic,
|
|
54
|
+
removeTopic,
|
|
55
|
+
resetTopics,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
59
|
+
(window as any).logger = logger;
|
|
60
|
+
window.console = logger;
|
|
61
|
+
return logger;
|
|
62
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { cubicNoiseSample2, cubicNoiseConfig } from "./cubic";
|
|
2
|
+
|
|
3
|
+
describe("Cubic", () => {
|
|
4
|
+
it("computes noise", () => {
|
|
5
|
+
const coords: [number, number][] = [];
|
|
6
|
+
for (let i = 0; i < 100; i++) {
|
|
7
|
+
coords.push([Math.floor((Math.random() - 0.5) * 1000), Math.floor((Math.random() - 0.5) * 1000)]);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const noises = coords.map((c) => cubicNoiseSample2(cubicNoiseConfig(1000, 64, 16, 256, 256), c[0], c[1]));
|
|
11
|
+
console.log("coords", JSON.stringify(coords));
|
|
12
|
+
console.log("noises", JSON.stringify(noises));
|
|
13
|
+
});
|
|
14
|
+
});
|
package/src/cubic.ts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
const RND_A = 134775813;
|
|
2
|
+
const RND_B = 1103515245;
|
|
3
|
+
const ACCURACY = 1000;
|
|
4
|
+
|
|
5
|
+
export function randomize(seed: number, x: number, y: number) {
|
|
6
|
+
return (((((x ^ y) * RND_A) ^ (seed + x)) * (((RND_B * x) << 16) ^ (RND_B * y - RND_A))) >>> 0) / 4294967295;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function tile(coordinate: number, period: number) {
|
|
10
|
+
if (coordinate < 0) while (coordinate < 0) coordinate += period;
|
|
11
|
+
return coordinate % period;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function interpolate(a: number, b: number, c: number, d: number, x: number, s: number, scale: number) {
|
|
15
|
+
const p = d - c - (a - b);
|
|
16
|
+
return (b * Math.pow(s, 3) + x * (c * Math.pow(s, 2) + a * s * (-s + x) + x * (-(b + p) * s + p * x))) * scale;
|
|
17
|
+
|
|
18
|
+
// return (x) * ((x ) * ((x ) * p + (a - b - p)) + (c - a)) + b;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Config a cubic noise.
|
|
23
|
+
* @param {Number} seed A seed in the range [0, 1].
|
|
24
|
+
* @param {Number} [periodX] The number of units after which the x coordinate repeats.
|
|
25
|
+
* @param {Number} [periodY] The number of units after which the y coordinate repeats.
|
|
26
|
+
* @returns {Object} A configuration object used by noise functions.
|
|
27
|
+
*/
|
|
28
|
+
export function cubicNoiseConfig(
|
|
29
|
+
seed: number,
|
|
30
|
+
octave: number,
|
|
31
|
+
scale: number,
|
|
32
|
+
periodX = Number.MAX_SAFE_INTEGER,
|
|
33
|
+
periodY = Number.MAX_SAFE_INTEGER
|
|
34
|
+
) {
|
|
35
|
+
return {
|
|
36
|
+
seed: Math.floor(seed * Number.MAX_SAFE_INTEGER),
|
|
37
|
+
periodX: periodX,
|
|
38
|
+
periodY: periodY,
|
|
39
|
+
octave,
|
|
40
|
+
scale,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Sample 1D cubic noise.
|
|
46
|
+
* @param {Object} config A valid noise configuration.
|
|
47
|
+
* @param {Number} x The X position to sample at.
|
|
48
|
+
* @returns {Number} A noise value in the range [0, 1].
|
|
49
|
+
*/
|
|
50
|
+
export function cubicNoiseSample1(config: ReturnType<typeof cubicNoiseConfig>, x: number) {
|
|
51
|
+
const xi = Math.floor(x);
|
|
52
|
+
const lerp = x - xi;
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
interpolate(
|
|
56
|
+
randomize(config.seed, tile(xi - 1, config.periodX), 0),
|
|
57
|
+
randomize(config.seed, tile(xi, config.periodX), 0),
|
|
58
|
+
randomize(config.seed, tile(xi + 1, config.periodX), 0),
|
|
59
|
+
randomize(config.seed, tile(xi + 2, config.periodX), 0),
|
|
60
|
+
lerp,
|
|
61
|
+
1,
|
|
62
|
+
1
|
|
63
|
+
) *
|
|
64
|
+
0.666666 +
|
|
65
|
+
0.166666
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Sample 2D cubic noise.
|
|
71
|
+
* @param {Object} config A valid noise configuration.
|
|
72
|
+
* @param {Number} x The X position to sample at.
|
|
73
|
+
* @param {Number} y The Y position to sample at.
|
|
74
|
+
* @returns {Number} A noise value in the range [0, 1].
|
|
75
|
+
*/
|
|
76
|
+
export function cubicNoiseSample2(
|
|
77
|
+
{ octave, periodX, periodY, seed, scale }: ReturnType<typeof cubicNoiseConfig>,
|
|
78
|
+
x: number,
|
|
79
|
+
y: number
|
|
80
|
+
) {
|
|
81
|
+
const xi = Math.floor(x / octave);
|
|
82
|
+
const lerpX = Math.floor((x * ACCURACY) / octave) - xi * ACCURACY;
|
|
83
|
+
const yi = Math.floor(y / octave);
|
|
84
|
+
const lerpY = Math.floor((y * ACCURACY) / octave) - yi * ACCURACY;
|
|
85
|
+
const x0 = tile(xi - 1, periodX);
|
|
86
|
+
const x1 = tile(xi, periodX);
|
|
87
|
+
const x2 = tile(xi + 1, periodX);
|
|
88
|
+
const x3 = tile(xi + 2, periodX);
|
|
89
|
+
|
|
90
|
+
const xSamples = new Array(4);
|
|
91
|
+
|
|
92
|
+
for (let i = 0; i < 4; ++i) {
|
|
93
|
+
const y = tile(yi - 1 + i, periodY);
|
|
94
|
+
|
|
95
|
+
xSamples[i] = interpolate(
|
|
96
|
+
randomize(seed, x0, y),
|
|
97
|
+
randomize(seed, x1, y),
|
|
98
|
+
randomize(seed, x2, y),
|
|
99
|
+
randomize(seed, x3, y),
|
|
100
|
+
lerpX,
|
|
101
|
+
ACCURACY,
|
|
102
|
+
1
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return Math.floor(
|
|
107
|
+
interpolate(xSamples[0], xSamples[1], xSamples[2], xSamples[3], lerpY, ACCURACY, scale) / Math.pow(ACCURACY, 6)
|
|
108
|
+
);
|
|
109
|
+
}
|
package/src/deferred.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A convenient way to create a promise with resolve and reject functions.
|
|
3
|
+
* @returns Tuple with resolve function, reject function and promise.
|
|
4
|
+
*/
|
|
5
|
+
export function deferred<T>(): [(t: T) => void, (t: Error) => void, Promise<T>] {
|
|
6
|
+
let resolve: ((t: T) => void) | null = null;
|
|
7
|
+
let reject: ((t: Error) => void) | null = null;
|
|
8
|
+
const promise = new Promise<T>((r, rj) => {
|
|
9
|
+
resolve = (t: T) => r(t);
|
|
10
|
+
reject = (e: Error) => rj(e);
|
|
11
|
+
});
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13
|
+
return [resolve as any, reject as any, promise];
|
|
14
|
+
}
|