@lexical/compiler 0.0.0-bootstrap.0 → 0.49.1-nightly.20260901.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.
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ 'use strict'
10
+ const LexicalCompilerPureAnnotations = process.env.NODE_ENV !== 'production' ? require('./LexicalCompilerPureAnnotations.dev.js') : require('./LexicalCompilerPureAnnotations.prod.js');
11
+ module.exports = LexicalCompilerPureAnnotations;
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ * @flow strict
8
+ */
9
+
10
+ /**
11
+ * LexicalCompilerPureAnnotations
12
+ */
13
+
14
+ export type PureAnnotationsSourceMap = {
15
+ file?: string,
16
+ mappings: string,
17
+ names: Array<string>,
18
+ sources: Array<string>,
19
+ sourcesContent?: Array<string | null>,
20
+ version: number,
21
+ };
22
+
23
+ export type TransformPureAnnotationsOptions = {
24
+ filename?: string,
25
+ functions?: Iterable<string>,
26
+ inline?: boolean,
27
+ namespaces?: Iterable<string>,
28
+ parserPlugins?: ReadonlyArray<unknown>,
29
+ relativeImports?: boolean,
30
+ sourceMap?: boolean,
31
+ sources?: RegExp | ReadonlyArray<RegExp>,
32
+ strict?: boolean,
33
+ };
34
+
35
+ export type PureAnnotationsResult = {
36
+ code: string,
37
+ count: number,
38
+ inlined: number,
39
+ map?: PureAnnotationsSourceMap,
40
+ };
41
+
42
+ export type PureAnnotationsOptions = {
43
+ ...TransformPureAnnotationsOptions,
44
+ enforce?: 'post' | 'pre',
45
+ exclude?: RegExp | ReadonlyArray<RegExp>,
46
+ include?: RegExp | ReadonlyArray<RegExp>,
47
+ };
48
+
49
+ /**
50
+ * The structural shape of the returned plugin, assignable to Vite's and
51
+ * Rollup's `Plugin`.
52
+ */
53
+ export type PureAnnotationsPlugin = {
54
+ enforce?: 'post' | 'pre',
55
+ name: string,
56
+ transform(
57
+ code: string,
58
+ id: string,
59
+ ): {code: string, map: PureAnnotationsSourceMap | null} | null,
60
+ };
61
+
62
+ declare export var PURE_FACTORY_FUNCTIONS: ReadonlyArray<string>;
63
+ declare export var PURE_NAMESPACES: ReadonlyArray<string>;
64
+ declare export var INLINE_FACTORY_FORMS: ReadonlyMap<string, string>;
65
+
66
+ declare export function transformPureAnnotations(
67
+ code: string,
68
+ options?: TransformPureAnnotationsOptions,
69
+ ): PureAnnotationsResult | null;
70
+
71
+ declare export function pureCallNames(
72
+ code: string,
73
+ options?: TransformPureAnnotationsOptions,
74
+ ): {functions: ReadonlySet<string>, namespaces: ReadonlySet<string>};
75
+
76
+ declare export function pureAnnotations(
77
+ options?: PureAnnotationsOptions,
78
+ ): PureAnnotationsPlugin;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import * as modDev from './LexicalCompilerPureAnnotations.dev.mjs';
10
+ import * as modProd from './LexicalCompilerPureAnnotations.prod.mjs';
11
+ const mod = process.env.NODE_ENV !== 'production' ? modDev : modProd;
12
+ export const INLINE_FACTORY_FORMS = mod.INLINE_FACTORY_FORMS;
13
+ export const PURE_FACTORY_FUNCTIONS = mod.PURE_FACTORY_FUNCTIONS;
14
+ export const PURE_NAMESPACES = mod.PURE_NAMESPACES;
15
+ export const pureAnnotations = mod.pureAnnotations;
16
+ export const pureCallNames = mod.pureCallNames;
17
+ export const transformPureAnnotations = mod.transformPureAnnotations;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ const mod = await (process.env.NODE_ENV !== 'production' ? import('./LexicalCompilerPureAnnotations.dev.mjs') : import('./LexicalCompilerPureAnnotations.prod.mjs'));
10
+ export const INLINE_FACTORY_FORMS = mod.INLINE_FACTORY_FORMS;
11
+ export const PURE_FACTORY_FUNCTIONS = mod.PURE_FACTORY_FUNCTIONS;
12
+ export const PURE_NAMESPACES = mod.PURE_NAMESPACES;
13
+ export const pureAnnotations = mod.pureAnnotations;
14
+ export const pureCallNames = mod.pureCallNames;
15
+ export const transformPureAnnotations = mod.transformPureAnnotations;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ "use strict";var e=require("@babel/parser"),t=require("magic-string"),n=require("node:fs"),r=require("node:path");function o(e){var t=Object.create(null);if(e)for(var n in e)t[n]=e[n];return t.default=e,t}var s=/*#__PURE__*/o(n),i=/*#__PURE__*/o(r);const a=["configExtension","createCommand","createContextState","createImportState","createRenderState","createState","declarePeerDependency","defineExtension","defineImportRule","defineOverlayRules","domOverride","safeCast"],c=new Map([["configExtension",{form:"args"}],["declarePeerDependency",{form:"args"}],["defineExtension",{form:"identity"}],["defineImportRule",{form:"identity"}],["safeCast",{form:"identity"}]]),l=/^[^\S\n]*\*?[^\S\n]*@lexical-inline(?:[^\S\n]+(\S+))?[^\S\n]*$/m;class f extends Error{constructor(e){super(e),this.name="PureAnnotationsError"}}const u=/^[^\S\n]*\*?[^\S\n]*@lexical-pure-namespace[^\S\n]*$/m,p=new Set(["args","identity"]),d=["sel"],m=new Map(Array.from(c,([e,t])=>[e,t.form])),y={contentOnly:!0},h=/[#@]__PURE__/,S=/\.(?:[cm]?[jt]sx?)$/,g=[/^lexical$/,/^@lexical\//],x=/[#@]__NO_SIDE_EFFECTS__/,w=/\bfrom\s*['"]\./,v=new Set(["ArrayExpression","BigIntLiteral","BooleanLiteral","DecimalLiteral","Identifier","JSXElement","JSXFragment","NullLiteral","NumericLiteral","ObjectExpression","RegExpLiteral","StringLiteral","TemplateLiteral","ThisExpression"]),E=[".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs"],b=new Set(["Array","BigInt","Boolean","Map","Number","Object","RegExp","Set","String","Symbol","WeakMap","WeakSet"]),I=/[\\/]node_modules[\\/]/,C=new Set(["ArrowFunctionExpression","ClassAccessorProperty","ClassMethod","ClassPrivateMethod","ClassPrivateProperty","ClassProperty","FunctionDeclaration","FunctionExpression","ObjectMethod","PropertyDefinition","StaticBlock","TSDeclareMethod"]),_=new Set,M=new Set(["comments","extra","innerComments","leadingComments","loc","trailingComments"]);function j(e,t){const n="string"==typeof e?e:"",r=/\.[cm]?tsx?$/i.test(n),o=["explicitResourceManagement"];return r&&o.push("typescript"),r&&!/\.[cm]?tsx$/i.test(n)||o.push("jsx"),t?o.concat(t):o}function O(e,t){let n=t;for(;n>0&&/\s/.test(e[n-1]);)n--;if(n<4||"/"!==e[n-1]||"*"!==e[n-2])return null;const r=e.lastIndexOf("/*",n-2);return-1===r?null:{end:n,start:r,value:e.slice(r+2,n-2)}}function P(e,t){const n=O(e,t);return null!==n&&h.test(n.value)}function $(e,t,n,r){const{functions:o,namespaces:s}=t,i=r||{discarded:!1,shadowed:_,statementStarts:new Set};if(Array.isArray(e)){for(const r of e)$(r,t,n,{discarded:!1,shadowed:i.shadowed,statementStarts:i.statementStarts});return}if(!e||"object"!=typeof e||"string"!=typeof e.type)return;if(C.has(e.type))return;if("ExpressionStatement"===e.type&&i.statementStarts.add(e.expression.start),"CallExpression"===e.type&&e.callee){const t={discarded:i.discarded,statementStart:i.statementStarts.has(e.start)};if("Identifier"===e.callee.type&&o.has(e.callee.name)&&!i.shadowed.has(e.callee.name))n(e,t);else if(void 0!==s&&s.size>0){const r=function(e){for(let t=e;t;){if("Identifier"===t.type)return t.name;if("MemberExpression"===t.type)t=t.object;else{if("CallExpression"!==t.type)return null;t=t.callee}}return null}(e.callee);null!==r&&s.has(r)&&!i.shadowed.has(r)&&n(e,{...t,namespace:!0})}}const a=function(e){const t="BlockStatement"===e.type?e.body:"SwitchCase"===e.type?e.consequent:null;if(null===t)return null;let n=null;const r=e=>{n=n||new Set,n.add(e)};for(const e of t)if("VariableDeclaration"===e.type&&"var"!==e.kind)for(const t of e.declarations)"Identifier"===t.id.type&&r(t.id.name);else"FunctionDeclaration"!==e.type&&"ClassDeclaration"!==e.type||!e.id||r(e.id.name);return n}(e),c=null===a?i.shadowed:new Set([...i.shadowed,...a]);for(const r of Object.keys(e))if(!M.has(r)){const o=e[r];o&&"object"==typeof o&&$(o,t,n,{discarded:"ExpressionStatement"===e.type&&"expression"===r,shadowed:c,statementStarts:i.statementStarts})}}function A(e,t,n,r){if(Array.isArray(e))for(const o of e)A(o,t,n,r);else if(e&&"object"==typeof e&&"string"==typeof e.type){t(e,n,r);for(const n of Object.keys(e))if(!M.has(n)){const r=e[n];r&&"object"==typeof r&&A(r,t,e,n)}}}function D(e,t,n,r){const o=new Set(r.map(e=>e.callee)),s=new Set(r.map(e=>e.callee.name));if(0!==s.size){A(n,(e,t,n)=>{s.has(e.name)&&!o.has(e)&&function(e,t,n){if("Identifier"!==e.type&&"JSXIdentifier"!==e.type)return!1;if(!t)return!0;switch(t.type){case"ImportDefaultSpecifier":case"ImportNamespaceSpecifier":case"ImportSpecifier":return!1;case"ExportSpecifier":return"local"===n;case"OptionalMemberExpression":case"MemberExpression":return"property"!==n||!0===t.computed;case"ClassMethod":case"ClassProperty":case"ObjectMethod":case"ObjectProperty":return"key"!==n||!0===t.computed;default:return!0}}(e,t,n)&&s.delete(e.name)});for(const r of n.body){if("ImportDeclaration"!==r.type||"type"===r.importKind)continue;const{specifiers:n}=r,o=n.filter(e=>"ImportSpecifier"===e.type),i=o.filter(e=>"type"!==e.importKind&&s.has(e.local.name));if(0===i.length)continue;if(i.length<o.length){const t=new Set(i);for(let n=0;n<o.length;n++){if(!t.has(o[n]))continue;let r=n;for(;r+1<o.length&&t.has(o[r+1]);)r++;r+1<o.length?e.remove(o[n].start,o[r+1].start):e.remove(o[n-1].end,o[r].end),n=r}continue}const a=t.indexOf("}",o[o.length-1].end);if(o.length<n.length){const r=n[n.indexOf(o[0])-1];e.remove(t.indexOf(",",r.end),a+1);continue}e.remove(r.start,r.end)}}}function F(e,t,n,r,o){const s=O(t,n.start);null!==s&&h.test(s.value)&&e.remove(s.start,n.start);const i=n.arguments;if("identity"!==r.form)return e.overwrite(n.start,function(e,t){const n=t.typeArguments||t.typeParameters,r=Math.max(t.callee.end,n?n.end:t.callee.end);return e.indexOf("(",r)+1}(t,n),"([",y),void e.overwrite(n.end-1,n.end,"])",y);!0===o||!v.has(i[0].type)?(e.overwrite(n.start,i[0].start,"(",y),e.overwrite(i[0].end,n.end,")",y)):(e.remove(n.start,i[0].start),e.remove(i[0].end,n.end))}const k=new Map,N=new Map;function R(e,t){if(e)for(const n of e){const e=l.exec(n.value);if(e){const n=e[1]||"";if(!p.has(n)){throw new f(`@lexical/compiler: unknown @lexical-inline form ${n?`"${n}"`:"(none given)"}${t?` in ${t}`:""}. Write \`@lexical-inline <form>\` with one of: ${Array.from(p).sort().join(", ")}.`)}return n}}return null}function T(e){return null!=e&&e.some(e=>x.test(e.value))}function L(e,t){const n=new Map;for(const r of e.body){const e="ExportNamedDeclaration"===r.type&&r.declaration?r.declaration:r,o=(r.leadingComments||[]).concat(e===r?[]:e.leadingComments||[]),s=T(o),i=R(o,t);if("FunctionDeclaration"!==e.type&&"TSDeclareFunction"!==e.type||!e.id){if("VariableDeclaration"===e.type)for(const r of e.declarations){const e=(r.leadingComments||[]).concat(r.init&&r.init.leadingComments||[]);"Identifier"===r.id.type&&(s||T(e))&&n.set(r.id.name,i||R(e,t))}}else s&&n.set(e.id.name,i)}return n}function q(e,t){const n=i.resolve(i.dirname(e),t),r=k.get(n);if(void 0!==r)return r;const o=[],a=i.extname(n);if(""!==a&&(o.push(n),/^\.[cm]?js$/.test(a))){const e=n.slice(0,-a.length);o.push(e+a.replace("js","ts"),e+".tsx")}for(const e of E)o.push(n+e);for(const e of E)o.push(i.join(n,`index${e}`));let c=null;for(const e of o)try{if(s.statSync(e).isFile()){c=e;break}}catch(e){}return k.set(n,c),c}function B(e,t){return z(e,t).functions}function z(t,n){const r=N.get(t);if(void 0!==r)return r;let o=null;try{o=e.parse(s.readFileSync(t,"utf8"),{plugins:j(t,n),sourceType:"module"}).program}catch(e){}const i=null===o?{functions:new Map,namespaces:new Set}:{functions:L(o,t),namespaces:W(o)};return N.set(t,i),i}function U(e,t,n){const r=Y(n.sources,g),o=new Map;function s(e,t,n,r){const s=c.get(t),i=void 0!==s?r||n===s.form?s:void 0:n?{form:n}:void 0;o.set(e,{inline:i,name:t})}for(const[t,r]of L(e,n.filename))s(t,t,r,!1);for(const o of e.body){if("ImportDeclaration"!==o.type)continue;const e=o.source.value,i=G(r,e),a=!i&&!1!==n.relativeImports&&"string"==typeof n.filename&&e.startsWith(".");if(i||a)for(const r of o.specifiers){if("ImportSpecifier"!==r.type||"Identifier"!==r.imported.type)continue;if(i){t.has(r.imported.name)&&s(r.local.name,r.imported.name,null,!0);continue}const o=q(n.filename,e),a=null===o?void 0:B(o,n.parserPlugins).get(r.imported.name);void 0!==a&&s(r.local.name,r.imported.name,a,!1)}}return o}function W(e){const t=new Set,n=e=>(e||[]).some(e=>u.test(e.value));for(const r of e.body){const e="ExportNamedDeclaration"===r.type&&r.declaration?r.declaration:r,o=n(r.leadingComments);if("VariableDeclaration"===e.type)for(const r of e.declarations)"Identifier"===r.id.type&&(o||n(e.leadingComments)||n(r.leadingComments)||r.init&&n(r.init.leadingComments))&&t.add(r.id.name)}return t}function V(e,t){return z(e,t).namespaces}function J(e,t,n){const r=new Set,o=Y(n.sources,g);for(const t of W(e))r.add(t);for(const s of e.body){if("ImportDeclaration"!==s.type)continue;const e=s.source.value,i=G(o,e),a=!i&&!1!==n.relativeImports&&"string"==typeof n.filename&&e.startsWith(".");if(!i&&!a)continue;let c;for(const o of s.specifiers)if("ImportSpecifier"===o.type&&"Identifier"===o.imported.type)if(i)t.has(o.imported.name)&&r.add(o.local.name);else{if(void 0===c){const t=q(n.filename,e);c=null===t?new Set:V(t,n.parserPlugins)}c.has(o.imported.name)&&r.add(o.local.name)}}for(const t of e.body)if("VariableDeclaration"===t.type)for(const e of t.declarations)"Identifier"===e.id.type&&e.init&&"Identifier"===e.init.type&&r.has(e.init.name)&&r.add(e.id.name);return r}function X(e,t){const n=e=>{if(Array.isArray(e))e.forEach(n);else if(e&&"object"==typeof e&&"string"==typeof e.type&&!C.has(e.type)){"CallExpression"!==e.type&&"NewExpression"!==e.type&&"TaggedTemplateExpression"!==e.type||t(e);for(const t of Object.keys(e))M.has(t)||n(e[t])}};e.arguments.forEach(n)}function K(n,r){const o=r||{},s=new Set(o.functions||a),i=new Set(o.namespaces||d);if(!function(e,t,n){if(e.includes("__NO_SIDE_EFFECTS__")||e.includes("@lexical-pure-namespace")||w.test(e))return!0;for(const n of t)if(e.includes(n))return!0;for(const t of n)if(e.includes(t))return!0;return!1}(n,s,i))return null;const c=e.parse(n,{errorRecovery:!1,plugins:j(o.filename,o.parserPlugins),sourceFilename:o.filename,sourceType:"module"}),l=U(c.program,s,o),u=J(c.program,i,o);if(0===l.size&&0===u.size)return null;const p=new Set,m=[],y=[];$(c.program,{functions:l,namespaces:u},(e,t)=>{if(!0===t.namespace)return void(P(n,e.start)||p.add(e.start));y.push(e);const r=l.get(e.callee.name),s=!0===o.inline?r.inline:void 0;void 0!==s&&!t.discarded&&function(e,t){const n=e.arguments;return"identity"!==t.form||1===n.length&&"SpreadElement"!==n[0].type&&"SequenceExpression"!==n[0].type}(e,s)?m.push([e,s,t.statementStart]):P(n,e.start)||p.add(e.start)});const h=Array.from(p);if(!0===o.strict){const e=new Set(p);for(const[t]of m)e.add(t.start);!function(e,t,n,r){const o=[],s=new Set;for(const t of n)X(t,n=>{const i=n.callee||n.tag;if(r.has(n.start)||P(e,n.start)||s.has(n.start)||"Identifier"===i.type&&b.has(i.name))return;s.add(n.start);const a=e.slice(i.start,i.end).replace(/\s+/g," "),c=n.loc?`${n.loc.start.line}:${n.loc.start.column+1}`:"?";o.push(` ${c} ${a}(...) inside ${e.slice(t.callee.start,t.callee.end)}(...)`)});if(o.length>0)throw new f(`@lexical/compiler: ${o.length} call(s) evaluated inside a definition in ${t||"<unknown>"} are not known to be side-effect free, so the definition cannot be tree-shaken:\n${o.join("\n")}\nMake the call lazy, or declare the function side-effect free (@__NO_SIDE_EFFECTS__ plus the transform's \`functions\`/\`namespaces\` options) so that its calls are annotated too.`)}(n,o.filename,y,e)}if(0===h.length&&0===m.length)return null;const S=new t(n);for(const e of h)S.appendLeft(e,"/* @__PURE__ */");for(const[e,t,r]of m)F(S,n,e,t,r);return D(S,n,c.program,m.map(([e])=>e)),{code:S.toString(),count:h.length,inlined:m.length,map:!1===o.sourceMap?void 0:S.generateMap({hires:"boundary",source:o.filename})}}function Y(e,t){return void 0===e?t:Array.isArray(e)?e:[e]}function G(e,t){return e.some(e=>e.test(t))}const H=a,Q=d,Z=m;exports.INLINE_FACTORY_FORMS=Z,exports.PURE_FACTORY_FUNCTIONS=H,exports.PURE_NAMESPACES=Q,exports.pureAnnotations=function(e){return function(e){const t=e||{},n=new Set(t.functions||a),r=Y(t.include,[S]),o=Y(t.exclude,[]);return{enforce:void 0===t.enforce?"post":t.enforce,name:"@lexical/compiler",transform(e,s){const i=function(e){return e.replace(/[?#][\s\S]*$/,"")}(s);if(!G(r,i)||G(o,i))return null;const a=I.test(i);let c=null;try{c=K(e,{filename:i,functions:n,inline:t.inline,namespaces:t.namespaces,parserPlugins:t.parserPlugins,relativeImports:t.relativeImports,sourceMap:t.sourceMap,sources:t.sources,strict:!0===t.strict&&!a})}catch(e){if(e instanceof f&&!a)throw e;return this&&"function"==typeof this.warn&&this.warn(`@lexical/compiler could not parse ${s}, no annotations were added: ${e instanceof Error?e.message:String(e)}`),null}return null===c?null:{code:c.code,map:void 0===c.map?null:c.map}}}}(e)},exports.pureCallNames=function(t,n){return function(t,n){const r=n||{},o=new Set(r.functions||a),s=e.parse(t,{errorRecovery:!1,plugins:j(r.filename,r.parserPlugins),sourceFilename:r.filename,sourceType:"module"});return{functions:new Set(U(s.program,o,r).keys()),namespaces:J(s.program,new Set(r.namespaces||d),r)}}(t,n)},exports.transformPureAnnotations=function(e,t){return K(e,t)};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ import{parse as e}from"@babel/parser";import t from"magic-string";import*as n from"node:fs";import*as r from"node:path";const o=["configExtension","createCommand","createContextState","createImportState","createRenderState","createState","declarePeerDependency","defineExtension","defineImportRule","defineOverlayRules","domOverride","safeCast"],s=new Map([["configExtension",{form:"args"}],["declarePeerDependency",{form:"args"}],["defineExtension",{form:"identity"}],["defineImportRule",{form:"identity"}],["safeCast",{form:"identity"}]]),i=/^[^\S\n]*\*?[^\S\n]*@lexical-inline(?:[^\S\n]+(\S+))?[^\S\n]*$/m;class a extends Error{constructor(e){super(e),this.name="PureAnnotationsError"}}const c=/^[^\S\n]*\*?[^\S\n]*@lexical-pure-namespace[^\S\n]*$/m,l=new Set(["args","identity"]),f=["sel"],u=new Map(Array.from(s,([e,t])=>[e,t.form])),p={contentOnly:!0},d=/[#@]__PURE__/,m=/\.(?:[cm]?[jt]sx?)$/,y=[/^lexical$/,/^@lexical\//],h=/[#@]__NO_SIDE_EFFECTS__/,g=/\bfrom\s*['"]\./,S=new Set(["ArrayExpression","BigIntLiteral","BooleanLiteral","DecimalLiteral","Identifier","JSXElement","JSXFragment","NullLiteral","NumericLiteral","ObjectExpression","RegExpLiteral","StringLiteral","TemplateLiteral","ThisExpression"]),w=[".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs"],x=new Set(["Array","BigInt","Boolean","Map","Number","Object","RegExp","Set","String","Symbol","WeakMap","WeakSet"]),v=/[\\/]node_modules[\\/]/,E=new Set(["ArrowFunctionExpression","ClassAccessorProperty","ClassMethod","ClassPrivateMethod","ClassPrivateProperty","ClassProperty","FunctionDeclaration","FunctionExpression","ObjectMethod","PropertyDefinition","StaticBlock","TSDeclareMethod"]),b=new Set,I=new Set(["comments","extra","innerComments","leadingComments","loc","trailingComments"]);function C(e,t){const n="string"==typeof e?e:"",r=/\.[cm]?tsx?$/i.test(n),o=["explicitResourceManagement"];return r&&o.push("typescript"),r&&!/\.[cm]?tsx$/i.test(n)||o.push("jsx"),t?o.concat(t):o}function _(e,t){let n=t;for(;n>0&&/\s/.test(e[n-1]);)n--;if(n<4||"/"!==e[n-1]||"*"!==e[n-2])return null;const r=e.lastIndexOf("/*",n-2);return-1===r?null:{end:n,start:r,value:e.slice(r+2,n-2)}}function j(e,t){const n=_(e,t);return null!==n&&d.test(n.value)}function M(e,t,n,r){const{functions:o,namespaces:s}=t,i=r||{discarded:!1,shadowed:b,statementStarts:new Set};if(Array.isArray(e)){for(const r of e)M(r,t,n,{discarded:!1,shadowed:i.shadowed,statementStarts:i.statementStarts});return}if(!e||"object"!=typeof e||"string"!=typeof e.type)return;if(E.has(e.type))return;if("ExpressionStatement"===e.type&&i.statementStarts.add(e.expression.start),"CallExpression"===e.type&&e.callee){const t={discarded:i.discarded,statementStart:i.statementStarts.has(e.start)};if("Identifier"===e.callee.type&&o.has(e.callee.name)&&!i.shadowed.has(e.callee.name))n(e,t);else if(void 0!==s&&s.size>0){const r=function(e){for(let t=e;t;){if("Identifier"===t.type)return t.name;if("MemberExpression"===t.type)t=t.object;else{if("CallExpression"!==t.type)return null;t=t.callee}}return null}(e.callee);null!==r&&s.has(r)&&!i.shadowed.has(r)&&n(e,{...t,namespace:!0})}}const a=function(e){const t="BlockStatement"===e.type?e.body:"SwitchCase"===e.type?e.consequent:null;if(null===t)return null;let n=null;const r=e=>{n=n||new Set,n.add(e)};for(const e of t)if("VariableDeclaration"===e.type&&"var"!==e.kind)for(const t of e.declarations)"Identifier"===t.id.type&&r(t.id.name);else"FunctionDeclaration"!==e.type&&"ClassDeclaration"!==e.type||!e.id||r(e.id.name);return n}(e),c=null===a?i.shadowed:new Set([...i.shadowed,...a]);for(const r of Object.keys(e))if(!I.has(r)){const o=e[r];o&&"object"==typeof o&&M(o,t,n,{discarded:"ExpressionStatement"===e.type&&"expression"===r,shadowed:c,statementStarts:i.statementStarts})}}function $(e,t,n,r){if(Array.isArray(e))for(const o of e)$(o,t,n,r);else if(e&&"object"==typeof e&&"string"==typeof e.type){t(e,n,r);for(const n of Object.keys(e))if(!I.has(n)){const r=e[n];r&&"object"==typeof r&&$(r,t,e,n)}}}function D(e,t,n,r){const o=new Set(r.map(e=>e.callee)),s=new Set(r.map(e=>e.callee.name));if(0!==s.size){$(n,(e,t,n)=>{s.has(e.name)&&!o.has(e)&&function(e,t,n){if("Identifier"!==e.type&&"JSXIdentifier"!==e.type)return!1;if(!t)return!0;switch(t.type){case"ImportDefaultSpecifier":case"ImportNamespaceSpecifier":case"ImportSpecifier":return!1;case"ExportSpecifier":return"local"===n;case"OptionalMemberExpression":case"MemberExpression":return"property"!==n||!0===t.computed;case"ClassMethod":case"ClassProperty":case"ObjectMethod":case"ObjectProperty":return"key"!==n||!0===t.computed;default:return!0}}(e,t,n)&&s.delete(e.name)});for(const r of n.body){if("ImportDeclaration"!==r.type||"type"===r.importKind)continue;const{specifiers:n}=r,o=n.filter(e=>"ImportSpecifier"===e.type),i=o.filter(e=>"type"!==e.importKind&&s.has(e.local.name));if(0===i.length)continue;if(i.length<o.length){const t=new Set(i);for(let n=0;n<o.length;n++){if(!t.has(o[n]))continue;let r=n;for(;r+1<o.length&&t.has(o[r+1]);)r++;r+1<o.length?e.remove(o[n].start,o[r+1].start):e.remove(o[n-1].end,o[r].end),n=r}continue}const a=t.indexOf("}",o[o.length-1].end);if(o.length<n.length){const r=n[n.indexOf(o[0])-1];e.remove(t.indexOf(",",r.end),a+1);continue}e.remove(r.start,r.end)}}}function O(e,t,n,r,o){const s=_(t,n.start);null!==s&&d.test(s.value)&&e.remove(s.start,n.start);const i=n.arguments;if("identity"!==r.form)return e.overwrite(n.start,function(e,t){const n=t.typeArguments||t.typeParameters,r=Math.max(t.callee.end,n?n.end:t.callee.end);return e.indexOf("(",r)+1}(t,n),"([",p),void e.overwrite(n.end-1,n.end,"])",p);!0===o||!S.has(i[0].type)?(e.overwrite(n.start,i[0].start,"(",p),e.overwrite(i[0].end,n.end,")",p)):(e.remove(n.start,i[0].start),e.remove(i[0].end,n.end))}const P=new Map,A=new Map;function F(e,t){if(e)for(const n of e){const e=i.exec(n.value);if(e){const n=e[1]||"";if(!l.has(n)){throw new a(`@lexical/compiler: unknown @lexical-inline form ${n?`"${n}"`:"(none given)"}${t?` in ${t}`:""}. Write \`@lexical-inline <form>\` with one of: ${Array.from(l).sort().join(", ")}.`)}return n}}return null}function k(e){return null!=e&&e.some(e=>h.test(e.value))}function T(e,t){const n=new Map;for(const r of e.body){const e="ExportNamedDeclaration"===r.type&&r.declaration?r.declaration:r,o=(r.leadingComments||[]).concat(e===r?[]:e.leadingComments||[]),s=k(o),i=F(o,t);if("FunctionDeclaration"!==e.type&&"TSDeclareFunction"!==e.type||!e.id){if("VariableDeclaration"===e.type)for(const r of e.declarations){const e=(r.leadingComments||[]).concat(r.init&&r.init.leadingComments||[]);"Identifier"===r.id.type&&(s||k(e))&&n.set(r.id.name,i||F(e,t))}}else s&&n.set(e.id.name,i)}return n}function R(e,t){const o=r.resolve(r.dirname(e),t),s=P.get(o);if(void 0!==s)return s;const i=[],a=r.extname(o);if(""!==a&&(i.push(o),/^\.[cm]?js$/.test(a))){const e=o.slice(0,-a.length);i.push(e+a.replace("js","ts"),e+".tsx")}for(const e of w)i.push(o+e);for(const e of w)i.push(r.join(o,`index${e}`));let c=null;for(const e of i)try{if(n.statSync(e).isFile()){c=e;break}}catch(e){}return P.set(o,c),c}function N(e,t){return L(e,t).functions}function L(t,r){const o=A.get(t);if(void 0!==o)return o;let s=null;try{s=e(n.readFileSync(t,"utf8"),{plugins:C(t,r),sourceType:"module"}).program}catch(e){}const i=null===s?{functions:new Map,namespaces:new Set}:{functions:T(s,t),namespaces:z(s)};return A.set(t,i),i}function B(e,t,n){const r=q(n.sources,y),o=new Map;function i(e,t,n,r){const i=s.get(t),a=void 0!==i?r||n===i.form?i:void 0:n?{form:n}:void 0;o.set(e,{inline:a,name:t})}for(const[t,r]of T(e,n.filename))i(t,t,r,!1);for(const o of e.body){if("ImportDeclaration"!==o.type)continue;const e=o.source.value,s=K(r,e),a=!s&&!1!==n.relativeImports&&"string"==typeof n.filename&&e.startsWith(".");if(s||a)for(const r of o.specifiers){if("ImportSpecifier"!==r.type||"Identifier"!==r.imported.type)continue;if(s){t.has(r.imported.name)&&i(r.local.name,r.imported.name,null,!0);continue}const o=R(n.filename,e),a=null===o?void 0:N(o,n.parserPlugins).get(r.imported.name);void 0!==a&&i(r.local.name,r.imported.name,a,!1)}}return o}function z(e){const t=new Set,n=e=>(e||[]).some(e=>c.test(e.value));for(const r of e.body){const e="ExportNamedDeclaration"===r.type&&r.declaration?r.declaration:r,o=n(r.leadingComments);if("VariableDeclaration"===e.type)for(const r of e.declarations)"Identifier"===r.id.type&&(o||n(e.leadingComments)||n(r.leadingComments)||r.init&&n(r.init.leadingComments))&&t.add(r.id.name)}return t}function W(e,t){return L(e,t).namespaces}function V(e,t,n){const r=new Set,o=q(n.sources,y);for(const t of z(e))r.add(t);for(const s of e.body){if("ImportDeclaration"!==s.type)continue;const e=s.source.value,i=K(o,e),a=!i&&!1!==n.relativeImports&&"string"==typeof n.filename&&e.startsWith(".");if(!i&&!a)continue;let c;for(const o of s.specifiers)if("ImportSpecifier"===o.type&&"Identifier"===o.imported.type)if(i)t.has(o.imported.name)&&r.add(o.local.name);else{if(void 0===c){const t=R(n.filename,e);c=null===t?new Set:W(t,n.parserPlugins)}c.has(o.imported.name)&&r.add(o.local.name)}}for(const t of e.body)if("VariableDeclaration"===t.type)for(const e of t.declarations)"Identifier"===e.id.type&&e.init&&"Identifier"===e.init.type&&r.has(e.init.name)&&r.add(e.id.name);return r}function J(e,t){const n=e=>{if(Array.isArray(e))e.forEach(n);else if(e&&"object"==typeof e&&"string"==typeof e.type&&!E.has(e.type)){"CallExpression"!==e.type&&"NewExpression"!==e.type&&"TaggedTemplateExpression"!==e.type||t(e);for(const t of Object.keys(e))I.has(t)||n(e[t])}};e.arguments.forEach(n)}function X(n,r){const s=r||{},i=new Set(s.functions||o),c=new Set(s.namespaces||f);if(!function(e,t,n){if(e.includes("__NO_SIDE_EFFECTS__")||e.includes("@lexical-pure-namespace")||g.test(e))return!0;for(const n of t)if(e.includes(n))return!0;for(const t of n)if(e.includes(t))return!0;return!1}(n,i,c))return null;const l=e(n,{errorRecovery:!1,plugins:C(s.filename,s.parserPlugins),sourceFilename:s.filename,sourceType:"module"}),u=B(l.program,i,s),p=V(l.program,c,s);if(0===u.size&&0===p.size)return null;const d=new Set,m=[],y=[];M(l.program,{functions:u,namespaces:p},(e,t)=>{if(!0===t.namespace)return void(j(n,e.start)||d.add(e.start));y.push(e);const r=u.get(e.callee.name),o=!0===s.inline?r.inline:void 0;void 0!==o&&!t.discarded&&function(e,t){const n=e.arguments;return"identity"!==t.form||1===n.length&&"SpreadElement"!==n[0].type&&"SequenceExpression"!==n[0].type}(e,o)?m.push([e,o,t.statementStart]):j(n,e.start)||d.add(e.start)});const h=Array.from(d);if(!0===s.strict){const e=new Set(d);for(const[t]of m)e.add(t.start);!function(e,t,n,r){const o=[],s=new Set;for(const t of n)J(t,n=>{const i=n.callee||n.tag;if(r.has(n.start)||j(e,n.start)||s.has(n.start)||"Identifier"===i.type&&x.has(i.name))return;s.add(n.start);const a=e.slice(i.start,i.end).replace(/\s+/g," "),c=n.loc?`${n.loc.start.line}:${n.loc.start.column+1}`:"?";o.push(` ${c} ${a}(...) inside ${e.slice(t.callee.start,t.callee.end)}(...)`)});if(o.length>0)throw new a(`@lexical/compiler: ${o.length} call(s) evaluated inside a definition in ${t||"<unknown>"} are not known to be side-effect free, so the definition cannot be tree-shaken:\n${o.join("\n")}\nMake the call lazy, or declare the function side-effect free (@__NO_SIDE_EFFECTS__ plus the transform's \`functions\`/\`namespaces\` options) so that its calls are annotated too.`)}(n,s.filename,y,e)}if(0===h.length&&0===m.length)return null;const S=new t(n);for(const e of h)S.appendLeft(e,"/* @__PURE__ */");for(const[e,t,r]of m)O(S,n,e,t,r);return D(S,n,l.program,m.map(([e])=>e)),{code:S.toString(),count:h.length,inlined:m.length,map:!1===s.sourceMap?void 0:S.generateMap({hires:"boundary",source:s.filename})}}function q(e,t){return void 0===e?t:Array.isArray(e)?e:[e]}function K(e,t){return e.some(e=>e.test(t))}const U=o,G=f,H=u;function Q(e,t){return X(e,t)}function Y(t,n){return function(t,n){const r=n||{},s=new Set(r.functions||o),i=e(t,{errorRecovery:!1,plugins:C(r.filename,r.parserPlugins),sourceFilename:r.filename,sourceType:"module"});return{functions:new Set(B(i.program,s,r).keys()),namespaces:V(i.program,new Set(r.namespaces||f),r)}}(t,n)}function Z(e){return function(e){const t=e||{},n=new Set(t.functions||o),r=q(t.include,[m]),s=q(t.exclude,[]);return{enforce:void 0===t.enforce?"post":t.enforce,name:"@lexical/compiler",transform(e,o){const i=function(e){return e.replace(/[?#][\s\S]*$/,"")}(o);if(!K(r,i)||K(s,i))return null;const c=v.test(i);let l=null;try{l=X(e,{filename:i,functions:n,inline:t.inline,namespaces:t.namespaces,parserPlugins:t.parserPlugins,relativeImports:t.relativeImports,sourceMap:t.sourceMap,sources:t.sources,strict:!0===t.strict&&!c})}catch(e){if(e instanceof a&&!c)throw e;return this&&"function"==typeof this.warn&&this.warn(`@lexical/compiler could not parse ${o}, no annotations were added: ${e instanceof Error?e.message:String(e)}`),null}return null===l?null:{code:l.code,map:void 0===l.map?null:l.map}}}}(e)}export{H as INLINE_FACTORY_FORMS,U as PURE_FACTORY_FUNCTIONS,G as PURE_NAMESPACES,Z as pureAnnotations,Y as pureCallNames,Q as transformPureAnnotations};
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ /**
9
+ * The subset of a source map that bundlers consume, matching what
10
+ * `magic-string` produces. Declared structurally so this package needs no
11
+ * dependency on any particular bundler's types.
12
+ */
13
+ export interface PureAnnotationsSourceMap {
14
+ file?: string;
15
+ mappings: string;
16
+ names: string[];
17
+ sources: string[];
18
+ sourcesContent?: (string | null)[];
19
+ version: number;
20
+ }
21
+ export interface TransformPureAnnotationsOptions {
22
+ /**
23
+ * Path of the module being transformed, used to choose the TypeScript and
24
+ * JSX parser plugins (and named as the source map's source).
25
+ */
26
+ filename?: string;
27
+ /**
28
+ * Names of the factories whose module-scope calls are annotated. Defaults
29
+ * to {@link PURE_FACTORY_FUNCTIONS}.
30
+ */
31
+ functions?: Iterable<string>;
32
+ /**
33
+ * Replace calls to the factories whose result is a trivial expression over
34
+ * their arguments (`safeCast`, `defineExtension`, `configExtension`,
35
+ * `declarePeerDependency`, `defineImportRule`) with that expression rather
36
+ * than annotating them — a literal needs no annotation to be dropped, and
37
+ * nothing is left to pin the definition it appears in.
38
+ *
39
+ * Off by default, because it assumes the Lexical being built matches this
40
+ * package's version. Lexical's own build turns it on for the bundles it
41
+ * publishes.
42
+ */
43
+ inline?: boolean;
44
+ /**
45
+ * Imported objects whose method calls are side-effect free, so that
46
+ * `sel.tag('p').attr('data-x', true)` is annotated the way a call to a
47
+ * factory function is. Defaults to {@link PURE_NAMESPACES}.
48
+ */
49
+ namespaces?: Iterable<string>;
50
+ /** Extra `@babel/parser` plugins to parse the module with. */
51
+ parserPlugins?: readonly unknown[];
52
+ /**
53
+ * Set to false to skip reading relatively imported modules to look for a
54
+ * `__NO_SIDE_EFFECTS__` declaration. Defaults to true.
55
+ */
56
+ relativeImports?: boolean;
57
+ /** Set to false to skip source map generation. */
58
+ sourceMap?: boolean;
59
+ /**
60
+ * Module specifiers whose exports are trusted to be the factories, without
61
+ * reading the module they come from. Defaults to `lexical` and
62
+ * `@lexical/*`; a call to a same-named function from anywhere else is only
63
+ * annotated when the declaration it resolves to is itself marked
64
+ * `__NO_SIDE_EFFECTS__`.
65
+ */
66
+ sources?: RegExp | readonly RegExp[];
67
+ /**
68
+ * Throw when a call evaluated inside one of the definitions is not known
69
+ * to be side-effect free. Such a call pins the definition into every
70
+ * bundle that imports the module, however well annotated the definition
71
+ * itself is, so this turns a silent loss of tree-shaking into a build
72
+ * error naming the call. Off by default.
73
+ */
74
+ strict?: boolean;
75
+ }
76
+ export interface PureAnnotationsResult {
77
+ code: string;
78
+ /** The number of annotations that were inserted. */
79
+ count: number;
80
+ /**
81
+ * The number of calls that were replaced by the literal they would have
82
+ * returned. Always 0 unless `inline` is set.
83
+ */
84
+ inlined: number;
85
+ map?: PureAnnotationsSourceMap;
86
+ }
87
+ export interface PureAnnotationsOptions extends TransformPureAnnotationsOptions {
88
+ /**
89
+ * Vite plugin ordering. Defaults to `'post'` so the transform runs after
90
+ * TypeScript and JSX have been compiled away.
91
+ */
92
+ enforce?: 'post' | 'pre';
93
+ /** Module ids to skip. Defaults to none. */
94
+ exclude?: RegExp | readonly RegExp[];
95
+ /**
96
+ * Module ids to transform. Defaults to every `.js`/`.jsx`/`.ts`/`.tsx`
97
+ * (and `.mjs`/`.cjs`/`.mts`/`.cts`) module, including those in
98
+ * `node_modules` so that a Lexical package consumed through its `source`
99
+ * export condition is annotated.
100
+ */
101
+ include?: RegExp | readonly RegExp[];
102
+ }
103
+ /**
104
+ * The structural shape of the returned plugin. It is assignable to Vite's
105
+ * `Plugin` and to Rollup's `Plugin`, so it can be dropped into the `plugins`
106
+ * array of either.
107
+ */
108
+ export interface PureAnnotationsPlugin {
109
+ enforce?: 'post' | 'pre';
110
+ name: string;
111
+ transform(code: string, id: string): {
112
+ code: string;
113
+ map: PureAnnotationsSourceMap | null;
114
+ } | null;
115
+ }
116
+ /**
117
+ * The Lexical factories that are annotated with `__NO_SIDE_EFFECTS__` at
118
+ * their definition and whose module-scope call sites therefore need a
119
+ * `__PURE__` annotation for bundlers to tree-shake unused definitions.
120
+ */
121
+ export declare const PURE_FACTORY_FUNCTIONS: readonly string[];
122
+ /**
123
+ * Objects imported from a Lexical package whose method calls are
124
+ * side-effect free, so that a module-scope `sel.tag('p')` is annotated the
125
+ * way a factory call is. Only the outermost call of a chain is annotated:
126
+ * rollup, terser and esbuild all drop the whole chain from that one.
127
+ */
128
+ export declare const PURE_NAMESPACES: readonly string[];
129
+ /**
130
+ * The factories that `inline` replaces with a literal, and the form each one
131
+ * takes: `identity` returns its single argument and `args` returns all of its
132
+ * arguments as an array. Each is marked `@lexical-inline <form>` where it is
133
+ * defined.
134
+ */
135
+ export declare const INLINE_FACTORY_FORMS: ReadonlyMap<string, string>;
136
+ /**
137
+ * Insert a `__PURE__` annotation before every module-scope call to one of the
138
+ * side-effect-free Lexical factories that does not already have one. Returns
139
+ * `null` when the module needs no annotations.
140
+ */
141
+ export declare function transformPureAnnotations(code: string, options?: TransformPureAnnotationsOptions): PureAnnotationsResult | null;
142
+ /**
143
+ * The local names in `code` whose module-scope calls the transform would
144
+ * annotate: `functions` are called directly, `namespaces` are objects whose
145
+ * method calls are annotated. A name qualifies by being imported from a
146
+ * Lexical package, declared in the module as side-effect free, or imported
147
+ * from a relative module that declares it that way. For tooling that needs
148
+ * the same decision without rewriting the module — a lint rule that removes
149
+ * a hand-written annotation only where the build puts one back. Throws on
150
+ * source it cannot parse.
151
+ */
152
+ export declare function pureCallNames(code: string, options?: TransformPureAnnotationsOptions): {
153
+ functions: ReadonlySet<string>;
154
+ namespaces: ReadonlySet<string>;
155
+ };
156
+ /**
157
+ * A Vite/Rollup plugin that inserts the `__PURE__` annotations that let
158
+ * bundlers tree-shake unused Lexical extension, command, and rule
159
+ * definitions.
160
+ *
161
+ * The published `dist` bundles already carry the annotations, so this is for
162
+ * builds that compile Lexical from its TypeScript source (the `source`
163
+ * export condition, a git checkout, or a vendored copy) — and for annotating
164
+ * the extensions and commands your own application defines.
165
+ *
166
+ * ```js
167
+ * import {pureAnnotations} from '@lexical/compiler';
168
+ *
169
+ * export default defineConfig({plugins: [pureAnnotations()]});
170
+ * ```
171
+ */
172
+ export declare function pureAnnotations(options?: PureAnnotationsOptions): PureAnnotationsPlugin;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ export * from './PureAnnotations';
@@ -0,0 +1,246 @@
1
+ /**
2
+ * The identifier a member-expression callee is rooted at, so that every call
3
+ * in `sel.tag('p').attr('x')` resolves to `sel`.
4
+ *
5
+ * @param {any} callee
6
+ * @returns {null | string} the name, or null when the callee is not rooted
7
+ * at a plain identifier
8
+ */
9
+ export function rootObjectName(callee: any): null | string;
10
+ /**
11
+ * The local names in `code` whose module-scope calls this transform would
12
+ * annotate — the same decision {@link transformPureAnnotations} makes, for
13
+ * tooling that needs to ask about a module without rewriting it (Lexical's
14
+ * `no-pure-annotation` ESLint rule removes a hand-written annotation only
15
+ * for a name this returns, so that the build is guaranteed to put it back).
16
+ *
17
+ * `functions` are called directly, `namespaces` are the objects whose method
18
+ * calls (`sel.tag('p').attr('x')`) are annotated.
19
+ *
20
+ * @param {string} code
21
+ * @param {TransformPureAnnotationsOptions} [options]
22
+ * @returns {{functions: Set<string>, namespaces: Set<string>}}
23
+ */
24
+ export function pureCallNames(code: string, options?: TransformPureAnnotationsOptions): {
25
+ functions: Set<string>;
26
+ namespaces: Set<string>;
27
+ };
28
+ /**
29
+ * Insert a `__PURE__` annotation before every module-scope call to one of the
30
+ * side-effect-free Lexical factories that does not already have one.
31
+ *
32
+ * Returns `null` when the module needs no annotations, so a caller can pass
33
+ * the original source through untouched.
34
+ *
35
+ * @param {string} code
36
+ * @param {TransformPureAnnotationsOptions} [options]
37
+ * @returns {null | PureAnnotationsResult}
38
+ */
39
+ export function transformPureAnnotations(code: string, options?: TransformPureAnnotationsOptions): null | PureAnnotationsResult;
40
+ /**
41
+ * @typedef {Object} PureAnnotationsOptions
42
+ * @property {'post' | 'pre'} [enforce] Vite plugin ordering, `'post'` by
43
+ * default so the transform runs after TypeScript/JSX has been compiled away.
44
+ * @property {RegExp | ReadonlyArray<RegExp>} [exclude] Module ids to skip.
45
+ * @property {Iterable<string>} [functions] Names of the factories whose
46
+ * module-scope calls are annotated. Defaults to PURE_FACTORY_FUNCTIONS.
47
+ * @property {RegExp | ReadonlyArray<RegExp>} [include] Module ids to
48
+ * transform, defaults to every .js/.jsx/.ts/.tsx (and .mjs/.cjs/.mts/.cts)
49
+ * module.
50
+ * @property {boolean} [inline] Replace calls to the factories whose result
51
+ * is a trivial expression over their arguments with that expression,
52
+ * rather than annotating them. Off by default: it assumes the Lexical
53
+ * being built matches this package's version.
54
+ * @property {ReadonlyArray<any>} [parserPlugins] Extra Babel parser
55
+ * plugins, for syntax the defaults do not cover.
56
+ * @property {boolean} [relativeImports] Set to false to skip reading
57
+ * relatively imported modules to look for a NO_SIDE_EFFECTS declaration.
58
+ * @property {Iterable<string>} [namespaces] Imported objects whose
59
+ * method calls are side-effect free, defaults to PURE_NAMESPACES.
60
+ * @property {boolean} [sourceMap] Set to false to skip source map generation.
61
+ * @property {RegExp | ReadonlyArray<RegExp>} [sources] Module specifiers
62
+ * whose exports are trusted to be the factories, defaults to `lexical` and
63
+ * `@lexical/*`.
64
+ * @property {boolean} [strict] Throw when a call evaluated inside one of the
65
+ * definitions is not known to be side-effect free, since it pins the
66
+ * definition into every bundle that imports the module.
67
+ */
68
+ /**
69
+ * A Vite/Rollup plugin that inserts the `__PURE__` annotations that let
70
+ * bundlers tree-shake unused Lexical extension, command, and rule
71
+ * definitions. Use it when building Lexical (or your own extensions) from
72
+ * TypeScript source rather than from the published `dist` bundles, which
73
+ * already carry the annotations.
74
+ *
75
+ * @param {PureAnnotationsOptions} [options]
76
+ * @returns {any} the plugin object
77
+ */
78
+ export function pureAnnotations(options?: PureAnnotationsOptions): any;
79
+ /**
80
+ * The Lexical factories that are annotated with `__NO_SIDE_EFFECTS__` at
81
+ * their definition. That annotation is only honored by esbuild for calls in
82
+ * the same file as the definition (and not at all by webpack/terser), so
83
+ * every module-scope call site needs its own `__PURE__` annotation for
84
+ * bundlers to tree-shake unused extension/command/rule definitions out of
85
+ * application bundles.
86
+ *
87
+ * Argument-position calls (e.g. `configExtension` / `safeCast` inside a
88
+ * `defineExtension` config) matter too: a pure call is only removable when
89
+ * its arguments are also side-effect-free, so one unannotated nested call
90
+ * pins the entire enclosing definition.
91
+ *
92
+ * @type {ReadonlyArray<string>}
93
+ */
94
+ export const PURE_FACTORY_FUNCTIONS: ReadonlyArray<string>;
95
+ /**
96
+ * An error the author has to act on — a malformed marker, or a call this
97
+ * transform cannot prove is safe — as opposed to source it cannot parse.
98
+ * The plugin passes an unparseable module through with a warning; these it
99
+ * rethrows, because ignoring them would silently produce the bundle the
100
+ * author was trying to avoid.
101
+ */
102
+ export class PureAnnotationsError extends Error {
103
+ /** @param {string} message */
104
+ constructor(message: string);
105
+ }
106
+ /**
107
+ * Imported objects whose method calls are side-effect free, so that a
108
+ * module-scope call like `sel.tag('p').attr('data-x', true)` is annotated
109
+ * the same way a call to a factory function is. Only the outermost call of
110
+ * a chain is annotated: rollup, terser and esbuild all drop the whole chain
111
+ * from that one annotation.
112
+ *
113
+ * As with the factories, the name is only trusted when it is imported from
114
+ * a Lexical package.
115
+ */
116
+ export const PURE_NAMESPACES: string[];
117
+ /**
118
+ * The form each inlinable factory is replaced with, for the tests that keep
119
+ * this table honest and for anyone who wants to know what `inline` does.
120
+ *
121
+ * @type {ReadonlyMap<string, string>}
122
+ */
123
+ export const INLINE_FACTORY_FORMS: ReadonlyMap<string, string>;
124
+ export type TransformPureAnnotationsOptions = {
125
+ /**
126
+ * Path of the module being transformed, used
127
+ * to choose the TypeScript and JSX parser plugins.
128
+ */
129
+ filename?: string | undefined;
130
+ /**
131
+ * Names of the factories whose
132
+ * module-scope calls are annotated. Defaults to PURE_FACTORY_FUNCTIONS.
133
+ */
134
+ functions?: Iterable<string> | undefined;
135
+ /**
136
+ * Replace calls to the factories whose result
137
+ * is a trivial expression over their arguments with that expression,
138
+ * rather than annotating them. Off by default: it assumes the Lexical
139
+ * being built matches this package's version.
140
+ */
141
+ inline?: boolean | undefined;
142
+ /**
143
+ * Extra Babel parser
144
+ * plugins, for syntax the defaults do not cover.
145
+ */
146
+ parserPlugins?: readonly any[] | undefined;
147
+ /**
148
+ * Set to false to skip reading
149
+ * relatively imported modules to look for a NO_SIDE_EFFECTS declaration.
150
+ */
151
+ relativeImports?: boolean | undefined;
152
+ /**
153
+ * Imported objects whose
154
+ * method calls are side-effect free, defaults to PURE_NAMESPACES.
155
+ */
156
+ namespaces?: Iterable<string> | undefined;
157
+ /**
158
+ * Set to false to skip source map generation.
159
+ */
160
+ sourceMap?: boolean | undefined;
161
+ /**
162
+ * Module specifiers
163
+ * whose exports are trusted to be the factories, defaults to `lexical` and
164
+ * `@lexical/*`.
165
+ */
166
+ sources?: RegExp | readonly RegExp[] | undefined;
167
+ /**
168
+ * Throw when a call evaluated inside one of the
169
+ * definitions is not known to be side-effect free, since it pins the
170
+ * definition into every bundle that imports the module.
171
+ */
172
+ strict?: boolean | undefined;
173
+ };
174
+ export type PureAnnotationsResult = {
175
+ /**
176
+ * Number of annotations that were inserted.
177
+ */
178
+ count: number;
179
+ code: string;
180
+ /**
181
+ * Number of calls that were replaced by the
182
+ * literal they would have returned.
183
+ */
184
+ inlined: number;
185
+ map?: any;
186
+ };
187
+ export type PureAnnotationsOptions = {
188
+ /**
189
+ * Vite plugin ordering, `'post'` by
190
+ * default so the transform runs after TypeScript/JSX has been compiled away.
191
+ */
192
+ enforce?: "pre" | "post" | undefined;
193
+ /**
194
+ * Module ids to skip.
195
+ */
196
+ exclude?: RegExp | readonly RegExp[] | undefined;
197
+ /**
198
+ * Names of the factories whose
199
+ * module-scope calls are annotated. Defaults to PURE_FACTORY_FUNCTIONS.
200
+ */
201
+ functions?: Iterable<string> | undefined;
202
+ /**
203
+ * Module ids to
204
+ * transform, defaults to every .js/.jsx/.ts/.tsx (and .mjs/.cjs/.mts/.cts)
205
+ * module.
206
+ */
207
+ include?: RegExp | readonly RegExp[] | undefined;
208
+ /**
209
+ * Replace calls to the factories whose result
210
+ * is a trivial expression over their arguments with that expression,
211
+ * rather than annotating them. Off by default: it assumes the Lexical
212
+ * being built matches this package's version.
213
+ */
214
+ inline?: boolean | undefined;
215
+ /**
216
+ * Extra Babel parser
217
+ * plugins, for syntax the defaults do not cover.
218
+ */
219
+ parserPlugins?: readonly any[] | undefined;
220
+ /**
221
+ * Set to false to skip reading
222
+ * relatively imported modules to look for a NO_SIDE_EFFECTS declaration.
223
+ */
224
+ relativeImports?: boolean | undefined;
225
+ /**
226
+ * Imported objects whose
227
+ * method calls are side-effect free, defaults to PURE_NAMESPACES.
228
+ */
229
+ namespaces?: Iterable<string> | undefined;
230
+ /**
231
+ * Set to false to skip source map generation.
232
+ */
233
+ sourceMap?: boolean | undefined;
234
+ /**
235
+ * Module specifiers
236
+ * whose exports are trusted to be the factories, defaults to `lexical` and
237
+ * `@lexical/*`.
238
+ */
239
+ sources?: RegExp | readonly RegExp[] | undefined;
240
+ /**
241
+ * Throw when a call evaluated inside one of the
242
+ * definitions is not known to be side-effect free, since it pins the
243
+ * definition into every bundle that imports the module.
244
+ */
245
+ strict?: boolean | undefined;
246
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+
9
+ // You are seeing this declaration file because your TypeScript cannot read
10
+ // Lexical's types through the package.json "exports" field.
11
+ //
12
+ // Lexical requires TypeScript >= 5.2 with "moduleResolution" set to
13
+ // "bundler", "node16", or "nodenext". To fix this:
14
+ // 1. Upgrade TypeScript to >= 5.2.
15
+ // 2. In tsconfig.json set "moduleResolution" to "bundler" (recommended for
16
+ // apps/bundlers) or "node16" / "nodenext", and a matching "module".
17
+ import 'Lexical requires TypeScript >=5.2 with moduleResolution bundler, node16, or nodenext';
18
+ export {};