@fluid-experimental/attributor 2.0.0-rc.1.0.3 → 2.0.0-rc.2.0.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/{.eslintrc.js → .eslintrc.cjs} +6 -2
- package/{.mocharc.js → .mocharc.cjs} +1 -1
- package/CHANGELOG.md +4 -0
- package/{api-extractor-esm.json → api-extractor-cjs.json} +5 -1
- package/api-extractor-lint.json +1 -1
- package/api-extractor.json +1 -1
- package/api-report/attributor.api.md +1 -1
- package/dist/attributor-untrimmed.d.ts +6 -3
- package/dist/attributor.d.ts +3 -3
- package/dist/attributor.d.ts.map +1 -1
- package/dist/attributor.js +0 -1
- package/dist/attributor.js.map +1 -1
- package/dist/encoders.d.ts +10 -4
- package/dist/encoders.d.ts.map +1 -1
- package/dist/encoders.js +13 -7
- package/dist/encoders.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist/lz4Encoder.d.ts +2 -2
- package/dist/lz4Encoder.d.ts.map +1 -1
- package/dist/lz4Encoder.js +4 -0
- package/dist/lz4Encoder.js.map +1 -1
- package/dist/mixinAttributor.d.ts +7 -4
- package/dist/mixinAttributor.d.ts.map +1 -1
- package/dist/mixinAttributor.js +20 -15
- package/dist/mixinAttributor.js.map +1 -1
- package/dist/package.json +3 -0
- package/dist/stringInterner.d.ts +9 -6
- package/dist/stringInterner.d.ts.map +1 -1
- package/dist/stringInterner.js +9 -6
- package/dist/stringInterner.js.map +1 -1
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/{attributor-untrimmed.d.mts → attributor-untrimmed.d.ts} +6 -3
- package/lib/{attributor.d.mts → attributor.d.ts} +4 -4
- package/lib/attributor.d.ts.map +1 -0
- package/lib/{attributor.mjs → attributor.js} +5 -2
- package/lib/attributor.js.map +1 -0
- package/lib/{encoders.d.mts → encoders.d.ts} +11 -5
- package/lib/encoders.d.ts.map +1 -0
- package/lib/{encoders.mjs → encoders.js} +16 -6
- package/lib/encoders.js.map +1 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +7 -0
- package/lib/index.js.map +1 -0
- package/lib/lz4Encoder.d.ts +7 -0
- package/lib/lz4Encoder.d.ts.map +1 -0
- package/lib/{lz4Encoder.mjs → lz4Encoder.js} +9 -1
- package/lib/lz4Encoder.js.map +1 -0
- package/lib/{mixinAttributor.d.mts → mixinAttributor.d.ts} +8 -5
- package/lib/mixinAttributor.d.ts.map +1 -0
- package/lib/{mixinAttributor.mjs → mixinAttributor.js} +19 -14
- package/lib/mixinAttributor.js.map +1 -0
- package/lib/{stringInterner.d.mts → stringInterner.d.ts} +10 -7
- package/lib/stringInterner.d.ts.map +1 -0
- package/lib/{stringInterner.mjs → stringInterner.js} +10 -7
- package/lib/stringInterner.js.map +1 -0
- package/lib/test/attribution/dirname.cjs +16 -0
- package/lib/test/attribution/dirname.cjs.map +1 -0
- package/lib/test/attribution/sharedString.attribution.spec.js +398 -0
- package/lib/test/attribution/sharedString.attribution.spec.js.map +1 -0
- package/lib/test/attributor.spec.js +32 -0
- package/lib/test/attributor.spec.js.map +1 -0
- package/lib/test/attributorSerializer.spec.js +123 -0
- package/lib/test/attributorSerializer.spec.js.map +1 -0
- package/lib/test/deltaEncoder.spec.js +36 -0
- package/lib/test/deltaEncoder.spec.js.map +1 -0
- package/lib/test/lz4Encoder.spec.js +27 -0
- package/lib/test/lz4Encoder.spec.js.map +1 -0
- package/lib/test/mixinAttributor.spec.js +219 -0
- package/lib/test/mixinAttributor.spec.js.map +1 -0
- package/lib/test/opStreamAttributor.spec.js +43 -0
- package/lib/test/opStreamAttributor.spec.js.map +1 -0
- package/lib/test/stringInterner.spec.js +71 -0
- package/lib/test/stringInterner.spec.js.map +1 -0
- package/lib/test/utils.js +32 -0
- package/lib/test/utils.js.map +1 -0
- package/package.json +42 -59
- package/src/attributor.ts +8 -6
- package/src/encoders.ts +16 -11
- package/src/index.ts +3 -3
- package/src/lz4Encoder.ts +10 -6
- package/src/mixinAttributor.ts +41 -26
- package/src/stringInterner.ts +10 -7
- package/tsconfig.cjs.json +7 -0
- package/tsconfig.json +2 -5
- package/lib/attributor.d.mts.map +0 -1
- package/lib/attributor.mjs.map +0 -1
- package/lib/encoders.d.mts.map +0 -1
- package/lib/encoders.mjs.map +0 -1
- package/lib/index.d.mts +0 -3
- package/lib/index.d.mts.map +0 -1
- package/lib/index.mjs +0 -3
- package/lib/index.mjs.map +0 -1
- package/lib/lz4Encoder.d.mts +0 -7
- package/lib/lz4Encoder.d.mts.map +0 -1
- package/lib/lz4Encoder.mjs.map +0 -1
- package/lib/mixinAttributor.d.mts.map +0 -1
- package/lib/mixinAttributor.mjs.map +0 -1
- package/lib/stringInterner.d.mts.map +0 -1
- package/lib/stringInterner.mjs.map +0 -1
- /package/lib/{attributor-alpha.d.mts → attributor-alpha.d.ts} +0 -0
- /package/lib/{attributor-beta.d.mts → attributor-beta.d.ts} +0 -0
- /package/lib/{attributor-public.d.mts → attributor-public.d.ts} +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a mock {@link @fluidframework/container-definitions#IAudience} for testing.
|
|
3
|
+
*/
|
|
4
|
+
export function makeMockAudience(clientIds) {
|
|
5
|
+
const clients = new Map();
|
|
6
|
+
for (const [index, clientId] of clientIds.entries()) {
|
|
7
|
+
// eslint-disable-next-line unicorn/prefer-code-point
|
|
8
|
+
const stringId = String.fromCharCode(index + 65);
|
|
9
|
+
const name = stringId.repeat(10);
|
|
10
|
+
const userId = `${name}@microsoft.com`;
|
|
11
|
+
const email = userId;
|
|
12
|
+
const user = {
|
|
13
|
+
id: userId,
|
|
14
|
+
name,
|
|
15
|
+
email,
|
|
16
|
+
};
|
|
17
|
+
clients.set(clientId, {
|
|
18
|
+
mode: "write",
|
|
19
|
+
details: { capabilities: { interactive: true } },
|
|
20
|
+
permission: [],
|
|
21
|
+
user,
|
|
22
|
+
scopes: [],
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
26
|
+
return {
|
|
27
|
+
getMember: (clientId) => {
|
|
28
|
+
return clients.get(clientId);
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/test/utils.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAmB;IACnD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC3C,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,SAAS,CAAC,OAAO,EAAE,EAAE;QACpD,qDAAqD;QACrD,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACjC,MAAM,MAAM,GAAG,GAAG,IAAI,gBAAgB,CAAC;QACvC,MAAM,KAAK,GAAG,MAAM,CAAC;QACrB,MAAM,IAAI,GAAG;YACZ,EAAE,EAAE,MAAM;YACV,IAAI;YACJ,KAAK;SACL,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE;YACrB,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,EAAE,YAAY,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE;YAChD,UAAU,EAAE,EAAE;YACd,IAAI;YACJ,MAAM,EAAE,EAAE;SACV,CAAC,CAAC;KACH;IACD,yEAAyE;IACzE,OAAO;QACN,SAAS,EAAE,CAAC,QAAgB,EAAuB,EAAE;YACpD,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC;KACY,CAAC;AAChB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\nimport { type IClient } from \"@fluidframework/protocol-definitions\";\nimport { type IAudience } from \"@fluidframework/container-definitions\";\n\n/**\n * Creates a mock {@link @fluidframework/container-definitions#IAudience} for testing.\n */\nexport function makeMockAudience(clientIds: string[]): IAudience {\n\tconst clients = new Map<string, IClient>();\n\tfor (const [index, clientId] of clientIds.entries()) {\n\t\t// eslint-disable-next-line unicorn/prefer-code-point\n\t\tconst stringId = String.fromCharCode(index + 65);\n\t\tconst name = stringId.repeat(10);\n\t\tconst userId = `${name}@microsoft.com`;\n\t\tconst email = userId;\n\t\tconst user = {\n\t\t\tid: userId,\n\t\t\tname,\n\t\t\temail,\n\t\t};\n\t\tclients.set(clientId, {\n\t\t\tmode: \"write\",\n\t\t\tdetails: { capabilities: { interactive: true } },\n\t\t\tpermission: [],\n\t\t\tuser,\n\t\t\tscopes: [],\n\t\t});\n\t}\n\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\treturn {\n\t\tgetMember: (clientId: string): IClient | undefined => {\n\t\t\treturn clients.get(clientId);\n\t\t},\n\t} as IAudience;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluid-experimental/attributor",
|
|
3
|
-
"version": "2.0.0-rc.
|
|
3
|
+
"version": "2.0.0-rc.2.0.0",
|
|
4
4
|
"description": "Operation attributor",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -11,60 +11,40 @@
|
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"author": "Microsoft and contributors",
|
|
13
13
|
"sideEffects": false,
|
|
14
|
+
"type": "module",
|
|
14
15
|
"exports": {
|
|
15
16
|
".": {
|
|
16
17
|
"import": {
|
|
17
|
-
"types": "./lib/index.d.
|
|
18
|
-
"default": "./lib/index.
|
|
18
|
+
"types": "./lib/index.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
19
20
|
},
|
|
20
21
|
"require": {
|
|
21
22
|
"types": "./dist/index.d.ts",
|
|
22
23
|
"default": "./dist/index.js"
|
|
23
24
|
}
|
|
24
25
|
},
|
|
25
|
-
"./
|
|
26
|
-
"import": {
|
|
27
|
-
"types": "./lib/attributor-alpha.d.mts",
|
|
28
|
-
"default": "./lib/index.mjs"
|
|
29
|
-
},
|
|
30
|
-
"require": {
|
|
31
|
-
"types": "./dist/attributor-alpha.d.ts",
|
|
32
|
-
"default": "./dist/index.js"
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
"./beta": {
|
|
26
|
+
"./public": {
|
|
36
27
|
"import": {
|
|
37
|
-
"types": "./lib/attributor-
|
|
38
|
-
"default": "./lib/index.
|
|
28
|
+
"types": "./lib/attributor-public.d.ts",
|
|
29
|
+
"default": "./lib/index.js"
|
|
39
30
|
},
|
|
40
31
|
"require": {
|
|
41
|
-
"types": "./dist/attributor-
|
|
32
|
+
"types": "./dist/attributor-public.d.ts",
|
|
42
33
|
"default": "./dist/index.js"
|
|
43
34
|
}
|
|
44
35
|
},
|
|
45
36
|
"./internal": {
|
|
46
37
|
"import": {
|
|
47
|
-
"types": "./lib/index.d.
|
|
48
|
-
"default": "./lib/index.
|
|
38
|
+
"types": "./lib/index.d.ts",
|
|
39
|
+
"default": "./lib/index.js"
|
|
49
40
|
},
|
|
50
41
|
"require": {
|
|
51
42
|
"types": "./dist/index.d.ts",
|
|
52
43
|
"default": "./dist/index.js"
|
|
53
44
|
}
|
|
54
|
-
},
|
|
55
|
-
"./public": {
|
|
56
|
-
"import": {
|
|
57
|
-
"types": "./lib/attributor-public.d.mts",
|
|
58
|
-
"default": "./lib/index.mjs"
|
|
59
|
-
},
|
|
60
|
-
"require": {
|
|
61
|
-
"types": "./dist/attributor-public.d.ts",
|
|
62
|
-
"default": "./dist/index.js"
|
|
63
|
-
}
|
|
64
45
|
}
|
|
65
46
|
},
|
|
66
47
|
"main": "dist/index.js",
|
|
67
|
-
"module": "lib/index.mjs",
|
|
68
48
|
"types": "dist/index.d.ts",
|
|
69
49
|
"c8": {
|
|
70
50
|
"all": true,
|
|
@@ -87,45 +67,44 @@
|
|
|
87
67
|
"temp-directory": "nyc/.nyc_output"
|
|
88
68
|
},
|
|
89
69
|
"dependencies": {
|
|
90
|
-
"@fluid-internal/client-utils": ">=2.0.0-rc.
|
|
91
|
-
"@fluidframework/container-definitions": ">=2.0.0-rc.
|
|
92
|
-
"@fluidframework/container-runtime": ">=2.0.0-rc.
|
|
93
|
-
"@fluidframework/container-runtime-definitions": ">=2.0.0-rc.
|
|
94
|
-
"@fluidframework/core-interfaces": ">=2.0.0-rc.
|
|
95
|
-
"@fluidframework/core-utils": ">=2.0.0-rc.
|
|
96
|
-
"@fluidframework/datastore-definitions": ">=2.0.0-rc.
|
|
97
|
-
"@fluidframework/protocol-definitions": "^3.
|
|
98
|
-
"@fluidframework/runtime-definitions": ">=2.0.0-rc.
|
|
99
|
-
"@fluidframework/runtime-utils": ">=2.0.0-rc.
|
|
100
|
-
"@fluidframework/telemetry-utils": ">=2.0.0-rc.
|
|
70
|
+
"@fluid-internal/client-utils": ">=2.0.0-rc.2.0.0 <2.0.0-rc.2.1.0",
|
|
71
|
+
"@fluidframework/container-definitions": ">=2.0.0-rc.2.0.0 <2.0.0-rc.2.1.0",
|
|
72
|
+
"@fluidframework/container-runtime": ">=2.0.0-rc.2.0.0 <2.0.0-rc.2.1.0",
|
|
73
|
+
"@fluidframework/container-runtime-definitions": ">=2.0.0-rc.2.0.0 <2.0.0-rc.2.1.0",
|
|
74
|
+
"@fluidframework/core-interfaces": ">=2.0.0-rc.2.0.0 <2.0.0-rc.2.1.0",
|
|
75
|
+
"@fluidframework/core-utils": ">=2.0.0-rc.2.0.0 <2.0.0-rc.2.1.0",
|
|
76
|
+
"@fluidframework/datastore-definitions": ">=2.0.0-rc.2.0.0 <2.0.0-rc.2.1.0",
|
|
77
|
+
"@fluidframework/protocol-definitions": "^3.2.0",
|
|
78
|
+
"@fluidframework/runtime-definitions": ">=2.0.0-rc.2.0.0 <2.0.0-rc.2.1.0",
|
|
79
|
+
"@fluidframework/runtime-utils": ">=2.0.0-rc.2.0.0 <2.0.0-rc.2.1.0",
|
|
80
|
+
"@fluidframework/telemetry-utils": ">=2.0.0-rc.2.0.0 <2.0.0-rc.2.1.0",
|
|
101
81
|
"lz4js": "^0.2.0"
|
|
102
82
|
},
|
|
103
83
|
"devDependencies": {
|
|
104
84
|
"@arethetypeswrong/cli": "^0.13.3",
|
|
105
|
-
"@fluid-
|
|
106
|
-
"@fluid-
|
|
85
|
+
"@fluid-internal/mocha-test-setup": ">=2.0.0-rc.2.0.0 <2.0.0-rc.2.1.0",
|
|
86
|
+
"@fluid-private/stochastic-test-utils": ">=2.0.0-rc.2.0.0 <2.0.0-rc.2.1.0",
|
|
87
|
+
"@fluid-tools/build-cli": "^0.34.0",
|
|
107
88
|
"@fluidframework/build-common": "^2.0.3",
|
|
108
|
-
"@fluidframework/build-tools": "^0.
|
|
109
|
-
"@fluidframework/driver-definitions": ">=2.0.0-rc.
|
|
110
|
-
"@fluidframework/eslint-config-fluid": "^
|
|
111
|
-
"@fluidframework/merge-tree": ">=2.0.0-rc.
|
|
112
|
-
"@fluidframework/
|
|
113
|
-
"@fluidframework/
|
|
114
|
-
"@
|
|
115
|
-
"@microsoft/api-extractor": "^7.38.3",
|
|
89
|
+
"@fluidframework/build-tools": "^0.34.0",
|
|
90
|
+
"@fluidframework/driver-definitions": ">=2.0.0-rc.2.0.0 <2.0.0-rc.2.1.0",
|
|
91
|
+
"@fluidframework/eslint-config-fluid": "^4.0.0",
|
|
92
|
+
"@fluidframework/merge-tree": ">=2.0.0-rc.2.0.0 <2.0.0-rc.2.1.0",
|
|
93
|
+
"@fluidframework/sequence": ">=2.0.0-rc.2.0.0 <2.0.0-rc.2.1.0",
|
|
94
|
+
"@fluidframework/test-runtime-utils": ">=2.0.0-rc.2.0.0 <2.0.0-rc.2.1.0",
|
|
95
|
+
"@microsoft/api-extractor": "^7.42.3",
|
|
116
96
|
"@types/mocha": "^9.1.1",
|
|
117
97
|
"@types/node": "^18.19.0",
|
|
118
98
|
"c8": "^8.0.1",
|
|
119
99
|
"copyfiles": "^2.4.1",
|
|
120
100
|
"cross-env": "^7.0.3",
|
|
121
|
-
"eslint": "~8.
|
|
101
|
+
"eslint": "~8.55.0",
|
|
122
102
|
"mocha": "^10.2.0",
|
|
123
103
|
"mocha-json-output-reporter": "^2.0.1",
|
|
124
104
|
"mocha-multi-reporters": "^1.5.1",
|
|
125
105
|
"moment": "^2.21.0",
|
|
126
106
|
"prettier": "~3.0.3",
|
|
127
107
|
"rimraf": "^4.4.0",
|
|
128
|
-
"tsc-multi": "^1.1.0",
|
|
129
108
|
"typescript": "~5.1.6"
|
|
130
109
|
},
|
|
131
110
|
"fluidBuild": {
|
|
@@ -146,14 +125,16 @@
|
|
|
146
125
|
},
|
|
147
126
|
"scripts": {
|
|
148
127
|
"api": "fluid-build . --task api",
|
|
149
|
-
"api-extractor:commonjs": "api-extractor run --
|
|
150
|
-
"api-extractor:esnext": "api-extractor run --
|
|
128
|
+
"api-extractor:commonjs": "api-extractor run --config ./api-extractor-cjs.json",
|
|
129
|
+
"api-extractor:esnext": "api-extractor run --local",
|
|
151
130
|
"build": "fluid-build . --task build",
|
|
152
131
|
"build:commonjs": "fluid-build . --task commonjs",
|
|
153
132
|
"build:compile": "fluid-build . --task compile",
|
|
154
133
|
"build:docs": "fluid-build . --task api",
|
|
155
|
-
"build:esnext": "tsc
|
|
156
|
-
"build:test": "
|
|
134
|
+
"build:esnext": "tsc --project ./tsconfig.json",
|
|
135
|
+
"build:test": "npm run build:test:esm && npm run build:test:cjs",
|
|
136
|
+
"build:test:cjs": "fluid-tsc commonjs --project ./src/test/tsconfig.cjs.json",
|
|
137
|
+
"build:test:esm": "tsc --project ./src/test/tsconfig.json",
|
|
157
138
|
"check:are-the-types-wrong": "attw --pack . --entrypoints .",
|
|
158
139
|
"check:release-tags": "api-extractor run --local --config ./api-extractor-lint.json",
|
|
159
140
|
"ci:build:docs": "api-extractor run",
|
|
@@ -167,9 +148,11 @@
|
|
|
167
148
|
"prettier:fix": "prettier --write . --cache --ignore-path ../../../.prettierignore",
|
|
168
149
|
"test": "npm run test:mocha",
|
|
169
150
|
"test:coverage": "c8 npm test",
|
|
170
|
-
"test:mocha": "
|
|
151
|
+
"test:mocha": "npm run test:mocha:esm && echo skipping cjs to avoid overhead - npm run test:mocha:cjs",
|
|
152
|
+
"test:mocha:cjs": "mocha --recursive \"dist/test/**/*.spec.*js\" --exit",
|
|
153
|
+
"test:mocha:esm": "mocha --recursive \"lib/test/**/*.spec.*js\" --exit",
|
|
171
154
|
"test:mocha:verbose": "cross-env FLUID_TEST_VERBOSE=1 npm run test:mocha",
|
|
172
|
-
"tsc": "tsc",
|
|
155
|
+
"tsc": "fluid-tsc commonjs --project ./tsconfig.cjs.json && copyfiles -f ../../../common/build/build-common/src/cjs/package.json ./dist",
|
|
173
156
|
"typetests:gen": "fluid-type-test-generator",
|
|
174
157
|
"typetests:prepare": "flub typetests --dir . --reset --previous --normalize"
|
|
175
158
|
}
|
package/src/attributor.ts
CHANGED
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { assert } from "@fluidframework/core-utils";
|
|
6
|
-
import {
|
|
7
|
-
|
|
6
|
+
import {
|
|
7
|
+
type IDocumentMessage,
|
|
8
|
+
type ISequencedDocumentMessage,
|
|
9
|
+
} from "@fluidframework/protocol-definitions";
|
|
10
|
+
import { type AttributionInfo } from "@fluidframework/runtime-definitions";
|
|
8
11
|
import { UsageError } from "@fluidframework/telemetry-utils";
|
|
9
|
-
import { IAudience, IDeltaManager } from "@fluidframework/container-definitions";
|
|
12
|
+
import { type IAudience, type IDeltaManager } from "@fluidframework/container-definitions";
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* Provides lookup between attribution keys and their associated attribution information.
|
|
@@ -45,7 +48,7 @@ export class Attributor implements IAttributor {
|
|
|
45
48
|
/**
|
|
46
49
|
* @param initialEntries - Any entries which should be populated on instantiation.
|
|
47
50
|
*/
|
|
48
|
-
constructor(initialEntries?: Iterable<[number, AttributionInfo]>) {
|
|
51
|
+
public constructor(initialEntries?: Iterable<[number, AttributionInfo]>) {
|
|
49
52
|
this.keyToInfo = new Map(initialEntries ?? []);
|
|
50
53
|
}
|
|
51
54
|
|
|
@@ -81,7 +84,7 @@ export class Attributor implements IAttributor {
|
|
|
81
84
|
* @internal
|
|
82
85
|
*/
|
|
83
86
|
export class OpStreamAttributor extends Attributor implements IAttributor {
|
|
84
|
-
constructor(
|
|
87
|
+
public constructor(
|
|
85
88
|
deltaManager: IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>,
|
|
86
89
|
audience: IAudience,
|
|
87
90
|
initialEntries?: Iterable<[number, AttributionInfo]>,
|
|
@@ -89,7 +92,6 @@ export class OpStreamAttributor extends Attributor implements IAttributor {
|
|
|
89
92
|
super(initialEntries);
|
|
90
93
|
deltaManager.on("op", (message: ISequencedDocumentMessage) => {
|
|
91
94
|
// TODO: Verify whether this should be able to handle server-generated ops (with null clientId)
|
|
92
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
93
95
|
const client = audience.getMember(message.clientId as string);
|
|
94
96
|
if (message.type === "op") {
|
|
95
97
|
// TODO: This case may be legitimate, and if so we need to figure out how to handle it.
|
package/src/encoders.ts
CHANGED
|
@@ -3,14 +3,13 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { assert } from "@fluidframework/core-utils";
|
|
6
|
-
import { IUser } from "@fluidframework/protocol-definitions";
|
|
7
|
-
import { AttributionInfo } from "@fluidframework/runtime-definitions";
|
|
8
|
-
import { IAttributor } from "./attributor";
|
|
9
|
-
import { InternedStringId, MutableStringInterner } from "./stringInterner";
|
|
6
|
+
import { type IUser } from "@fluidframework/protocol-definitions";
|
|
7
|
+
import { type AttributionInfo } from "@fluidframework/runtime-definitions";
|
|
8
|
+
import { type IAttributor } from "./attributor.js";
|
|
9
|
+
import { type InternedStringId, MutableStringInterner } from "./stringInterner.js";
|
|
10
10
|
|
|
11
11
|
export interface Encoder<TDecoded, TEncoded> {
|
|
12
12
|
encode(decoded: TDecoded): TEncoded;
|
|
13
|
-
|
|
14
13
|
decode(encoded: TEncoded): TDecoded;
|
|
15
14
|
}
|
|
16
15
|
|
|
@@ -20,7 +19,7 @@ export type TimestampEncoder = Encoder<number[], number[]>;
|
|
|
20
19
|
|
|
21
20
|
export const deltaEncoder: TimestampEncoder = {
|
|
22
21
|
encode: (timestamps: number[]) => {
|
|
23
|
-
const deltaTimestamps: number[] =
|
|
22
|
+
const deltaTimestamps: number[] = Array.from({ length: timestamps.length });
|
|
24
23
|
let prev = 0;
|
|
25
24
|
for (let i = 0; i < timestamps.length; i++) {
|
|
26
25
|
deltaTimestamps[i] = timestamps[i] - prev;
|
|
@@ -33,7 +32,7 @@ export const deltaEncoder: TimestampEncoder = {
|
|
|
33
32
|
Array.isArray(encoded),
|
|
34
33
|
0x4b0 /* Encoded timestamps should be an array of numbers */,
|
|
35
34
|
);
|
|
36
|
-
const timestamps: number[] =
|
|
35
|
+
const timestamps: number[] = Array.from({ length: encoded.length });
|
|
37
36
|
let cumulativeSum = 0;
|
|
38
37
|
for (let i = 0; i < encoded.length; i++) {
|
|
39
38
|
cumulativeSum += encoded[i];
|
|
@@ -53,13 +52,16 @@ export interface SerializedAttributor {
|
|
|
53
52
|
}
|
|
54
53
|
|
|
55
54
|
export class AttributorSerializer implements IAttributorSerializer {
|
|
56
|
-
constructor(
|
|
55
|
+
public constructor(
|
|
57
56
|
private readonly makeAttributor: (
|
|
58
57
|
entries: Iterable<[number, AttributionInfo]>,
|
|
59
58
|
) => IAttributor,
|
|
60
59
|
private readonly timestampEncoder: TimestampEncoder,
|
|
61
60
|
) {}
|
|
62
61
|
|
|
62
|
+
/**
|
|
63
|
+
* {@inheritDoc Encoder.encode}
|
|
64
|
+
*/
|
|
63
65
|
public encode(attributor: IAttributor): SerializedAttributor {
|
|
64
66
|
const interner = new MutableStringInterner();
|
|
65
67
|
const seqs: number[] = [];
|
|
@@ -82,6 +84,9 @@ export class AttributorSerializer implements IAttributorSerializer {
|
|
|
82
84
|
return serialized;
|
|
83
85
|
}
|
|
84
86
|
|
|
87
|
+
/**
|
|
88
|
+
* {@inheritDoc Encoder.decode}
|
|
89
|
+
*/
|
|
85
90
|
public decode(encoded: SerializedAttributor): IAttributor {
|
|
86
91
|
const interner = new MutableStringInterner(encoded.interner);
|
|
87
92
|
const { seqs, timestamps: encodedTimestamps, attributionRefs } = encoded;
|
|
@@ -90,12 +95,12 @@ export class AttributorSerializer implements IAttributorSerializer {
|
|
|
90
95
|
seqs.length === timestamps.length && timestamps.length === attributionRefs.length,
|
|
91
96
|
0x4b1 /* serialized attribution columns should have the same length */,
|
|
92
97
|
);
|
|
93
|
-
const entries =
|
|
98
|
+
const entries: [number, AttributionInfo][] = Array.from({ length: seqs.length });
|
|
94
99
|
for (let i = 0; i < seqs.length; i++) {
|
|
95
100
|
const key = seqs[i];
|
|
96
101
|
const timestamp = timestamps[i];
|
|
97
102
|
const ref = attributionRefs[i];
|
|
98
|
-
const user
|
|
103
|
+
const user = JSON.parse(interner.getString(ref)) as IUser;
|
|
99
104
|
entries[i] = [key, { user, timestamp }];
|
|
100
105
|
}
|
|
101
106
|
return this.makeAttributor(entries);
|
|
@@ -103,7 +108,7 @@ export class AttributorSerializer implements IAttributorSerializer {
|
|
|
103
108
|
}
|
|
104
109
|
|
|
105
110
|
/**
|
|
106
|
-
*
|
|
111
|
+
* Creates an encoder which composes `a` and `b`.
|
|
107
112
|
*/
|
|
108
113
|
export const chain = <T1, T2, T3>(a: Encoder<T1, T2>, b: Encoder<T2, T3>): Encoder<T1, T3> => ({
|
|
109
114
|
encode: (content) => b.encode(a.encode(content)),
|
package/src/index.ts
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
export { Attributor,
|
|
5
|
+
export { Attributor, type IAttributor, OpStreamAttributor } from "./attributor.js";
|
|
6
6
|
export {
|
|
7
7
|
createRuntimeAttributor,
|
|
8
8
|
enableOnNewFileKey,
|
|
9
|
-
IProvideRuntimeAttributor,
|
|
9
|
+
type IProvideRuntimeAttributor,
|
|
10
10
|
IRuntimeAttributor,
|
|
11
11
|
mixinAttributor,
|
|
12
|
-
} from "./mixinAttributor";
|
|
12
|
+
} from "./mixinAttributor.js";
|
package/src/lz4Encoder.ts
CHANGED
|
@@ -4,23 +4,27 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { compress, decompress } from "lz4js";
|
|
6
6
|
import { bufferToString, stringToBuffer } from "@fluid-internal/client-utils";
|
|
7
|
-
import { Jsonable } from "@fluidframework/datastore-definitions";
|
|
8
|
-
import { Encoder } from "./encoders";
|
|
7
|
+
import { type Jsonable } from "@fluidframework/datastore-definitions";
|
|
8
|
+
import { type Encoder } from "./encoders.js";
|
|
9
9
|
|
|
10
|
+
// TODO: document this
|
|
11
|
+
// eslint-disable-next-line jsdoc/require-description
|
|
10
12
|
/**
|
|
11
13
|
* @alpha
|
|
12
14
|
*/
|
|
13
15
|
export function makeLZ4Encoder<T>(): Encoder<Jsonable<T>, string> {
|
|
14
16
|
return {
|
|
15
|
-
encode: (decoded: Jsonable<T>) => {
|
|
17
|
+
encode: (decoded: Jsonable<T>): string => {
|
|
16
18
|
const uncompressed = new TextEncoder().encode(JSON.stringify(decoded));
|
|
17
|
-
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
20
|
+
const compressed = compress(uncompressed) as ArrayBufferLike;
|
|
18
21
|
return bufferToString(compressed, "base64");
|
|
19
22
|
},
|
|
20
23
|
decode: (serializedSummary: string): Jsonable<T> => {
|
|
21
24
|
const compressed = new Uint8Array(stringToBuffer(serializedSummary, "base64"));
|
|
22
|
-
|
|
23
|
-
const
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
26
|
+
const uncompressed = decompress(compressed) as BufferSource;
|
|
27
|
+
const decoded = JSON.parse(new TextDecoder().decode(uncompressed)) as Jsonable<T>;
|
|
24
28
|
return decoded;
|
|
25
29
|
},
|
|
26
30
|
};
|
package/src/mixinAttributor.ts
CHANGED
|
@@ -3,23 +3,27 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import {
|
|
6
|
-
IDocumentMessage,
|
|
7
|
-
ISequencedDocumentMessage,
|
|
8
|
-
ISnapshotTree,
|
|
6
|
+
type IDocumentMessage,
|
|
7
|
+
type ISequencedDocumentMessage,
|
|
8
|
+
type ISnapshotTree,
|
|
9
9
|
} from "@fluidframework/protocol-definitions";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
type IAudience,
|
|
12
|
+
type IContainerContext,
|
|
13
|
+
type IDeltaManager,
|
|
14
|
+
} from "@fluidframework/container-definitions";
|
|
11
15
|
import { ContainerRuntime } from "@fluidframework/container-runtime";
|
|
12
16
|
import type { IContainerRuntimeOptions } from "@fluidframework/container-runtime";
|
|
13
17
|
import {
|
|
14
|
-
AttributionInfo,
|
|
15
|
-
AttributionKey,
|
|
16
|
-
ISummaryTreeWithStats,
|
|
17
|
-
ITelemetryContext,
|
|
18
|
-
NamedFluidDataStoreRegistryEntries,
|
|
18
|
+
type AttributionInfo,
|
|
19
|
+
type AttributionKey,
|
|
20
|
+
type ISummaryTreeWithStats,
|
|
21
|
+
type ITelemetryContext,
|
|
22
|
+
type NamedFluidDataStoreRegistryEntries,
|
|
19
23
|
} from "@fluidframework/runtime-definitions";
|
|
20
24
|
import { addSummarizeResultToSummary, SummaryTreeBuilder } from "@fluidframework/runtime-utils";
|
|
21
|
-
import { IContainerRuntime } from "@fluidframework/container-runtime-definitions";
|
|
22
|
-
import { IRequest, IResponse, FluidObject } from "@fluidframework/core-interfaces";
|
|
25
|
+
import { type IContainerRuntime } from "@fluidframework/container-runtime-definitions";
|
|
26
|
+
import { type IRequest, type IResponse, type FluidObject } from "@fluidframework/core-interfaces";
|
|
23
27
|
import { bufferToString } from "@fluid-internal/client-utils";
|
|
24
28
|
import { assert, unreachableCase } from "@fluidframework/core-utils";
|
|
25
29
|
import {
|
|
@@ -28,9 +32,9 @@ import {
|
|
|
28
32
|
PerformanceEvent,
|
|
29
33
|
UsageError,
|
|
30
34
|
} from "@fluidframework/telemetry-utils";
|
|
31
|
-
import { Attributor, IAttributor, OpStreamAttributor } from "./attributor";
|
|
32
|
-
import { AttributorSerializer, chain, deltaEncoder, Encoder } from "./encoders";
|
|
33
|
-
import { makeLZ4Encoder } from "./lz4Encoder";
|
|
35
|
+
import { Attributor, type IAttributor, OpStreamAttributor } from "./attributor.js";
|
|
36
|
+
import { AttributorSerializer, chain, deltaEncoder, type Encoder } from "./encoders.js";
|
|
37
|
+
import { makeLZ4Encoder } from "./lz4Encoder.js";
|
|
34
38
|
|
|
35
39
|
// Summary tree keys
|
|
36
40
|
const attributorTreeName = ".attributor";
|
|
@@ -56,7 +60,8 @@ export interface IProvideRuntimeAttributor {
|
|
|
56
60
|
/**
|
|
57
61
|
* Provides access to attribution information stored on the container runtime.
|
|
58
62
|
*
|
|
59
|
-
* Attributors are only populated after the container runtime they are injected
|
|
63
|
+
* @remarks Attributors are only populated after the container runtime into which they are being injected has initialized.
|
|
64
|
+
*
|
|
60
65
|
* @sealed
|
|
61
66
|
* @internal
|
|
62
67
|
*/
|
|
@@ -79,8 +84,10 @@ export interface IRuntimeAttributor extends IProvideRuntimeAttributor {
|
|
|
79
84
|
}
|
|
80
85
|
|
|
81
86
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
87
|
+
* Creates an `IRuntimeAttributor` for usage with {@link mixinAttributor}.
|
|
88
|
+
*
|
|
89
|
+
* @remarks The attributor will only be populated with data once it's passed via scope to a container runtime load flow.
|
|
90
|
+
*
|
|
84
91
|
* @internal
|
|
85
92
|
*/
|
|
86
93
|
export function createRuntimeAttributor(): IRuntimeAttributor {
|
|
@@ -98,7 +105,9 @@ export function createRuntimeAttributor(): IRuntimeAttributor {
|
|
|
98
105
|
* @param Base - base class, inherits from FluidAttributorRuntime
|
|
99
106
|
* @internal
|
|
100
107
|
*/
|
|
101
|
-
export const mixinAttributor = (
|
|
108
|
+
export const mixinAttributor = (
|
|
109
|
+
Base: typeof ContainerRuntime = ContainerRuntime,
|
|
110
|
+
): typeof ContainerRuntime =>
|
|
102
111
|
class ContainerRuntimeWithAttributor extends Base {
|
|
103
112
|
public static async loadRuntime(params: {
|
|
104
113
|
context: IContainerContext;
|
|
@@ -107,7 +116,9 @@ export const mixinAttributor = (Base: typeof ContainerRuntime = ContainerRuntime
|
|
|
107
116
|
runtimeOptions?: IContainerRuntimeOptions;
|
|
108
117
|
containerScope?: FluidObject;
|
|
109
118
|
containerRuntimeCtor?: typeof ContainerRuntime;
|
|
110
|
-
/**
|
|
119
|
+
/**
|
|
120
|
+
* @deprecated Will be removed once Loader LTS version is "2.0.0-internal.7.0.0". Migrate all usage of IFluidRouter to the "entryPoint" pattern. Refer to Removing-IFluidRouter.md
|
|
121
|
+
*/
|
|
111
122
|
requestHandler?: (request: IRequest, runtime: IContainerRuntime) => Promise<IResponse>;
|
|
112
123
|
provideEntryPoint: (containerRuntime: IContainerRuntime) => Promise<FluidObject>;
|
|
113
124
|
}): Promise<ContainerRuntime> {
|
|
@@ -137,19 +148,22 @@ export const mixinAttributor = (Base: typeof ContainerRuntime = ContainerRuntime
|
|
|
137
148
|
const baseSnapshot: ISnapshotTree | undefined =
|
|
138
149
|
pendingRuntimeState?.baseSnapshot ?? context.baseSnapshot;
|
|
139
150
|
|
|
140
|
-
const { audience, deltaManager } = context;
|
|
151
|
+
const { audience, deltaManager, taggedLogger } = context;
|
|
141
152
|
assert(
|
|
142
153
|
audience !== undefined,
|
|
143
154
|
0x508 /* Audience must exist when instantiating attribution-providing runtime */,
|
|
144
155
|
);
|
|
145
156
|
|
|
146
|
-
const mc = loggerToMonitoringContext(
|
|
157
|
+
const mc = loggerToMonitoringContext(taggedLogger);
|
|
147
158
|
|
|
148
159
|
const shouldTrackAttribution = mc.config.getBoolean(enableOnNewFileKey) ?? false;
|
|
149
160
|
if (shouldTrackAttribution) {
|
|
150
|
-
|
|
161
|
+
const { options } = context;
|
|
162
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
163
|
+
(options.attribution ??= {}).track = true;
|
|
151
164
|
}
|
|
152
165
|
|
|
166
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
153
167
|
const runtime = (await Base.loadRuntime({
|
|
154
168
|
context,
|
|
155
169
|
registryEntries,
|
|
@@ -161,6 +175,7 @@ export const mixinAttributor = (Base: typeof ContainerRuntime = ContainerRuntime
|
|
|
161
175
|
containerScope,
|
|
162
176
|
existing,
|
|
163
177
|
containerRuntimeCtor,
|
|
178
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
164
179
|
} as any)) as ContainerRuntimeWithAttributor;
|
|
165
180
|
runtime.runtimeAttributor = runtimeAttributor as RuntimeAttributor;
|
|
166
181
|
|
|
@@ -202,7 +217,7 @@ export const mixinAttributor = (Base: typeof ContainerRuntime = ContainerRuntime
|
|
|
202
217
|
fullTree: boolean,
|
|
203
218
|
trackState: boolean,
|
|
204
219
|
telemetryContext?: ITelemetryContext,
|
|
205
|
-
) {
|
|
220
|
+
): void {
|
|
206
221
|
super.addContainerStateToSummary(summaryTree, fullTree, trackState, telemetryContext);
|
|
207
222
|
const attributorSummary = this.runtimeAttributor?.summarize();
|
|
208
223
|
if (attributorSummary) {
|
|
@@ -286,7 +301,9 @@ class RuntimeAttributor implements IRuntimeAttributor {
|
|
|
286
301
|
makeLZ4Encoder(),
|
|
287
302
|
);
|
|
288
303
|
|
|
289
|
-
if (attributorTree
|
|
304
|
+
if (attributorTree === undefined) {
|
|
305
|
+
this.opAttributor = new OpStreamAttributor(deltaManager, audience);
|
|
306
|
+
} else {
|
|
290
307
|
const id = attributorTree.blobs[opBlobName];
|
|
291
308
|
assert(
|
|
292
309
|
id !== undefined,
|
|
@@ -295,8 +312,6 @@ class RuntimeAttributor implements IRuntimeAttributor {
|
|
|
295
312
|
const blobContents = await readBlob(id);
|
|
296
313
|
const attributorSnapshot = bufferToString(blobContents, "utf8");
|
|
297
314
|
this.opAttributor = this.encoder.decode(attributorSnapshot);
|
|
298
|
-
} else {
|
|
299
|
-
this.opAttributor = new OpStreamAttributor(deltaManager, audience);
|
|
300
315
|
}
|
|
301
316
|
}
|
|
302
317
|
|
package/src/stringInterner.ts
CHANGED
|
@@ -36,15 +36,15 @@ export class MutableStringInterner implements StringInterner {
|
|
|
36
36
|
* @param inputStrings - A list of strings to intern in the order given. Can be used to rehydrate from a previous
|
|
37
37
|
* `StringInterner`'s {@link StringInterner.getSerializable} return value.
|
|
38
38
|
*/
|
|
39
|
-
constructor(inputStrings: readonly string[] = []) {
|
|
39
|
+
public constructor(inputStrings: readonly string[] = []) {
|
|
40
40
|
for (const value of inputStrings) {
|
|
41
41
|
this.getOrCreateInternedId(value);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
*
|
|
47
|
-
* @
|
|
46
|
+
* Creates an intern ID that is uniquely associated with the input string.
|
|
47
|
+
* @param input - The string to get the associated intern ID for.
|
|
48
48
|
*/
|
|
49
49
|
public getOrCreateInternedId(input: string): InternedStringId {
|
|
50
50
|
return this.getInternedId(input) ?? this.createNewId(input);
|
|
@@ -55,10 +55,9 @@ export class MutableStringInterner implements StringInterner {
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
|
-
*
|
|
58
|
+
* Creates a string that is uniquely associated with the given intern ID.
|
|
59
59
|
* @param internId - The intern ID to get the associated string for. Can only retrieve strings that have been
|
|
60
60
|
* used as inputs to calls of `getInternId`.
|
|
61
|
-
* @returns a string that is uniquely associated with the given intern ID
|
|
62
61
|
*/
|
|
63
62
|
public getString(internId: number): string {
|
|
64
63
|
const result = this.internedStrings[internId];
|
|
@@ -69,14 +68,18 @@ export class MutableStringInterner implements StringInterner {
|
|
|
69
68
|
}
|
|
70
69
|
|
|
71
70
|
/**
|
|
72
|
-
*
|
|
71
|
+
* Gets the list of strings interned where the indices map to the associated {@link InternedStringId} of
|
|
73
72
|
* each string.
|
|
74
73
|
*/
|
|
75
74
|
public getSerializable(): readonly string[] {
|
|
76
75
|
return this.internedStrings;
|
|
77
76
|
}
|
|
78
77
|
|
|
79
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* Create a new interned id.
|
|
80
|
+
*
|
|
81
|
+
* @remarks Assumes (without validation) that the input doesn't already have an interned id.
|
|
82
|
+
*/
|
|
80
83
|
private createNewId(input: string): InternedStringId {
|
|
81
84
|
const internedId = this.stringToInternedIdMap.size as InternedStringId;
|
|
82
85
|
this.stringToInternedIdMap.set(input, internedId);
|
package/tsconfig.json
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"extends":
|
|
3
|
-
"../../../common/build/build-common/tsconfig.base.json",
|
|
4
|
-
"../../../common/build/build-common/tsconfig.cjs.json",
|
|
5
|
-
],
|
|
2
|
+
"extends": "../../../common/build/build-common/tsconfig.node16.json",
|
|
6
3
|
"include": ["src/**/*"],
|
|
7
4
|
"exclude": ["src/test/**/*"],
|
|
8
5
|
"compilerOptions": {
|
|
9
6
|
"rootDir": "./src",
|
|
10
|
-
"outDir": "./
|
|
7
|
+
"outDir": "./lib",
|
|
11
8
|
},
|
|
12
9
|
}
|
package/lib/attributor.d.mts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"attributor.d.mts","sourceRoot":"","sources":["../src/attributor.ts"],"names":[],"mappings":"OAKO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,sCAAsC;OAC3F,EAAE,eAAe,EAAE,MAAM,qCAAqC;OAE9D,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,uCAAuC;AAEhF;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC3B;;;;OAIG;IACH,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAC;IAEjD;;;OAGG;IACH,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAAC;IAEhE;;OAEG;IACH,OAAO,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;CAIvD;AAED;;;GAGG;AACH,qBAAa,UAAW,YAAW,WAAW;IAC7C,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAE3D;;OAEG;gBACS,cAAc,CAAC,EAAE,QAAQ,CAAC,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAIhE;;OAEG;IACI,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe;IAQvD;;OAEG;IACI,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAItE;;OAEG;IACI,OAAO,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAG7D;AAED;;;;GAIG;AACH,qBAAa,kBAAmB,SAAQ,UAAW,YAAW,WAAW;gBAEvE,YAAY,EAAE,aAAa,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,EACxE,QAAQ,EAAE,SAAS,EACnB,cAAc,CAAC,EAAE,QAAQ,CAAC,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAoBrD"}
|