@cloudcare/hvigor-ohos-plugin 0.1.1 → 0.1.2-alpha.2
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 +15 -1
- package/README.md +53 -6
- package/hvigorCompile/ft-cold-launch-transform.ts +668 -121
- package/hvigorCompile/ft-console-log-transform.ts +90 -96
- package/hvigorCompile/ft-generated-names.ts +19 -0
- package/hvigorCompile/ft-lexical-scope.ts +65 -0
- package/hvigorCompile/ft-session-replay-transform.ts +381 -0
- package/hvigorCompile/ft-source-transform-host.ts +112 -23
- package/hvigorCompile/ft-transform-context.ts +91 -0
- package/hvigorCompile/ft-web-replay-transform.ts +61 -0
- package/index.js +5 -3
- package/package.json +12 -3
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/** Associate every native Web with its controller without replacing application IDs or callbacks. */
|
|
2
|
+
import { isApplicationArkTsSource } from './ft-console-log-transform';
|
|
3
|
+
import { hasRuntimeDependency, SourceReader, SourceDiagnosticReporter, parseApplicationSource,
|
|
4
|
+
reportSourceDiagnostic, reportSourceParseError } from './ft-transform-context';
|
|
5
|
+
import { createLexicalResolver } from './ft-lexical-scope';
|
|
6
|
+
import { allocateName, collectIdentifierNames } from './ft-generated-names';
|
|
7
|
+
|
|
8
|
+
type TypeScriptApi = any;
|
|
9
|
+
interface Injection { position: number; content: string; }
|
|
10
|
+
|
|
11
|
+
const MARKER = '/* guance-web-replay-transform:instrumented */';
|
|
12
|
+
const SDK_IMPORT = '@guancecloud/ft_sdk/Index';
|
|
13
|
+
|
|
14
|
+
export function transformWebReplaySource(ts: TypeScriptApi, id: string, code: string, readSource?: SourceReader,
|
|
15
|
+
reportDiagnostic?: SourceDiagnosticReporter): string {
|
|
16
|
+
if (!isApplicationArkTsSource(id) || code.includes(MARKER) ||
|
|
17
|
+
!hasRuntimeDependency(ts, id, '@guancecloud/ft_sdk', readSource) ||
|
|
18
|
+
!hasRuntimeDependency(ts, id, '@guancecloud/ft_session_replay', readSource)) return code;
|
|
19
|
+
|
|
20
|
+
const source = ts.createSourceFile(id, code, ts.ScriptTarget.Latest, true, ts.ScriptKind.ETS ?? ts.ScriptKind.TS);
|
|
21
|
+
const identifiers = collectIdentifierNames(ts, source);
|
|
22
|
+
const constructors: any[] = [];
|
|
23
|
+
const unsupported: any[] = [];
|
|
24
|
+
const resolve = createLexicalResolver(ts, source);
|
|
25
|
+
let importEnd = 0;
|
|
26
|
+
const visit = (node: any): void => {
|
|
27
|
+
if (ts.isImportDeclaration(node)) importEnd = Math.max(importEnd, node.end);
|
|
28
|
+
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === 'Web' &&
|
|
29
|
+
!resolve(node.expression, 'Web')) {
|
|
30
|
+
if (node.arguments.length === 1 && !ts.isSpreadElement(node.arguments[0]) &&
|
|
31
|
+
!(ts.isOptionalChain && ts.isOptionalChain(node))) constructors.push(node);
|
|
32
|
+
else unsupported.push(node);
|
|
33
|
+
}
|
|
34
|
+
ts.forEachChild(node, visit);
|
|
35
|
+
};
|
|
36
|
+
visit(source);
|
|
37
|
+
if (constructors.length === 0 && unsupported.length === 0) return code;
|
|
38
|
+
if (reportSourceParseError(ts, parseApplicationSource(ts, id, code), reportDiagnostic)) return code;
|
|
39
|
+
unsupported.forEach(node => reportSourceDiagnostic(source, node.getStart(source), 'unsupported-web-call',
|
|
40
|
+
'Automatic ArkWeb binding requires a non-optional Web(options) call with exactly one non-spread argument.', reportDiagnostic));
|
|
41
|
+
if (constructors.length === 0) return code;
|
|
42
|
+
|
|
43
|
+
const bridge = allocateName(identifiers, '__ftWebReplayBridge');
|
|
44
|
+
const injections: Injection[] = [];
|
|
45
|
+
for (const constructor of constructors) {
|
|
46
|
+
const options = constructor.arguments[0];
|
|
47
|
+
// Keep the pair adjacent, before any app modifier expression can evaluate another Web.
|
|
48
|
+
injections.push({ position: options.getStart(source), content: `${bridge}.prepare(` });
|
|
49
|
+
injections.push({ position: options.end, content: ')' });
|
|
50
|
+
injections.push({ position: constructor.end,
|
|
51
|
+
content: `.customProperty(${bridge}.PROPERTY, ${bridge}.consumeBindingId())` });
|
|
52
|
+
}
|
|
53
|
+
injections.push({ position: importEnd,
|
|
54
|
+
content: `\n${MARKER}\nimport { FTWebViewReplayBridge as ${bridge} } from '${SDK_IMPORT}';\n` });
|
|
55
|
+
injections.sort((left, right) => right.position - left.position);
|
|
56
|
+
let result = code;
|
|
57
|
+
for (const injection of injections) {
|
|
58
|
+
result = result.slice(0, injection.position) + injection.content + result.slice(injection.position);
|
|
59
|
+
}
|
|
60
|
+
return result;
|
|
61
|
+
}
|
package/index.js
CHANGED
|
@@ -4,11 +4,13 @@ const path = require('path');
|
|
|
4
4
|
const { OhosPluginId } = require('@ohos/hvigor-ohos-plugin');
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* Returns the HAP-level Hvigor plugin used to instrument console/HiLog calls
|
|
8
|
-
*
|
|
7
|
+
* Returns the HAP-level Hvigor plugin used to instrument console/HiLog calls,
|
|
8
|
+
* cold-launch lifecycle boundaries, Session Replay page roots and Web bindings before
|
|
9
|
+
* ArkTS compilation.
|
|
9
10
|
*
|
|
10
11
|
* This package intentionally contains build tooling only. Applications still
|
|
11
|
-
* need
|
|
12
|
+
* need their matching runtime HARs to receive instrumented calls. The Replay
|
|
13
|
+
* transform self-disables when @guancecloud/ft_session_replay is absent.
|
|
12
14
|
*/
|
|
13
15
|
function ftConsoleLogPlugin() {
|
|
14
16
|
return {
|
package/package.json
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcare/hvigor-ohos-plugin",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Guance HarmonyOS Hvigor plugin for
|
|
3
|
+
"version": "0.1.2-alpha.2",
|
|
4
|
+
"description": "Guance HarmonyOS Hvigor plugin for console, cold-launch, Session Replay page roots, and Web controller binding.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
7
7
|
"index.js",
|
|
8
8
|
"hvigorCompile/ft-source-transform-host.ts",
|
|
9
|
+
"hvigorCompile/ft-transform-context.ts",
|
|
10
|
+
"hvigorCompile/ft-lexical-scope.ts",
|
|
11
|
+
"hvigorCompile/ft-generated-names.ts",
|
|
9
12
|
"hvigorCompile/ft-console-log-transform.ts",
|
|
10
13
|
"hvigorCompile/ft-cold-launch-transform.ts",
|
|
14
|
+
"hvigorCompile/ft-session-replay-transform.ts",
|
|
15
|
+
"hvigorCompile/ft-web-replay-transform.ts",
|
|
11
16
|
"README.md",
|
|
12
17
|
"CHANGELOG.md",
|
|
13
18
|
"LICENSE"
|
|
@@ -27,11 +32,15 @@
|
|
|
27
32
|
"node": ">=18"
|
|
28
33
|
},
|
|
29
34
|
"peerDependencies": {
|
|
30
|
-
"@guancecloud/ft_sdk": ">=0.1.17"
|
|
35
|
+
"@guancecloud/ft_sdk": ">=0.1.17",
|
|
36
|
+
"@guancecloud/ft_session_replay": ">=0.1.0-alpha01"
|
|
31
37
|
},
|
|
32
38
|
"peerDependenciesMeta": {
|
|
33
39
|
"@guancecloud/ft_sdk": {
|
|
34
40
|
"optional": true
|
|
41
|
+
},
|
|
42
|
+
"@guancecloud/ft_session_replay": {
|
|
43
|
+
"optional": true
|
|
35
44
|
}
|
|
36
45
|
}
|
|
37
46
|
}
|