1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied. See the License for the
15 // specific language governing permissions and limitations
24 observableFromStreams
,
25 shouldRunInChildProcess
,
26 spawnGulpCommandInChildProcess
,
27 } = require('./util');
29 const fs
= require('fs');
30 const gulp
= require('gulp');
31 const path
= require('path');
32 const mkdirp
= require('mkdirp');
33 const sourcemaps
= require('gulp-sourcemaps');
34 const { memoizeTask
} = require('./memoize-task');
35 const { compileBinFiles
} = require('./typescript-task');
36 const closureCompiler
= require('google-closure-compiler').gulp();
38 const closureTask
= ((cache
) => memoizeTask(cache
, async
function closure(target
, format
) {
40 if (shouldRunInChildProcess(target
, format
)) {
41 return spawnGulpCommandInChildProcess('compile', target
, format
);
44 const src
= targetDir(target
, `cls`);
45 const srcAbsolute
= path
.resolve(src
);
46 const out
= targetDir(target
, format
);
47 const externs
= path
.join(`${out}/${mainExport}.externs.js`);
48 const entry_point
= path
.join(`${src}/${mainExport}.dom.cls.js`);
50 const exportedImports
= publicModulePaths(srcAbsolute
).reduce((entries
, publicModulePath
) => [
53 exports_
: getPublicExportedNames(esmRequire(publicModulePath
))
60 fs
.promises
.writeFile(externs
, generateExternsFile(exportedImports
)),
61 fs
.promises
.writeFile(entry_point
, generateUMDExportAssignment(srcAbsolute
, exportedImports
))
64 return await Promise
.all([
65 runClosureCompileAsObservable().toPromise(),
66 compileBinFiles(target
, format
).toPromise()
69 function runClosureCompileAsObservable() {
70 return observableFromStreams(
72 /* external libs first */
73 `node_modules/flatbuffers/package.json`,
74 `node_modules/flatbuffers/js/flatbuffers.mjs`,
75 `${src}/**/*.js` /* <-- then source globs */
78 closureCompiler(createClosureArgs(entry_point
, externs
, target
), {
79 platform
: ['native', 'java', 'javascript']
81 // rename the sourcemaps from *.js.map files to *.min.js.map
82 sourcemaps
.write(`.`, { mapFile
: (mapPath
) => mapPath
.replace(`.js.map`, `.${target}.min.js.map`) }),
88 module
.exports
= closureTask
;
89 module
.exports
.closureTask
= closureTask
;
91 const createClosureArgs
= (entry_point
, externs
, target
) => ({
95 warning_level
: `QUIET`,
96 dependency_mode
: `PRUNE`,
97 rewrite_polyfills
: false,
98 module_resolution
: `NODE`,
99 // formatting: `PRETTY_PRINT`,
101 compilation_level
: `ADVANCED`,
102 package_json_entry_names
: `module,jsnext:main,main`,
103 assume_function_wrapper
: true,
104 js_output_file
: `${mainExport}.js`,
105 language_in
: gCCLanguageNames
[`esnext`],
106 language_out
: gCCLanguageNames
[target
],
107 output_wrapper
:`${apacheHeader()}
108 (function (global, factory) {
109 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
110 typeof define === 'function' && define.amd ? define(['exports'], factory) :
111 (factory(global.Arrow = global.Arrow || {}));
112 }(this, (function (exports) {%output%}.bind(this))));`
115 function generateUMDExportAssignment(src
, exportedImports
) {
117 ...exportedImports
.map(({ publicModulePath
}, i
) => {
118 const p
= publicModulePath
.slice(src
.length
+ 1);
119 return (`import * as exports${i} from './${p}';`);
121 'Object.assign(arguments[0], exports0);'
125 function generateExternsFile(exportedImports
) {
128 ...exportedImports
.reduce((externBodies
, { exports_
}) => [
129 ...externBodies
, ...exports_
.map(externBody
)
130 ], []).filter(Boolean
)
134 function externBody({ exportName
, staticNames
, instanceNames
}) {
136 `var ${exportName} = function() {};`,
137 staticNames
.map((staticName
) => (isNaN(+staticName
)
138 ? `/** @type {?} */\n${exportName}.${staticName} = function() {};`
139 : `/** @type {?} */\n${exportName}[${staticName}] = function() {};`
141 instanceNames
.map((instanceName
) => (isNaN(+instanceName
)
142 ? `/** @type {?} */\n${exportName}.prototype.${instanceName};`
143 : `/** @type {?} */\n${exportName}.prototype[${instanceName}];`
145 ].filter(Boolean
).join('\n');
148 function externsHeader() {
149 return (`${apacheHeader()}
153 * @fileoverview Closure Compiler externs for Arrow
155 * @suppress {duplicate,checkTypes}
157 /** @type {symbol} */
159 /** @type {symbol} */
161 /** @type {symbol} */
162 Symbol.asyncIterator;
166 function getPublicExportedNames(entryModule
) {
167 const fn = function() {};
168 const isStaticOrProtoName
= (x
) => (
171 (x
!== `undefined`) &&
172 (x
!== `__esModule`) &&
173 (x
!== `constructor`) &&
177 .getOwnPropertyNames(entryModule
)
178 .filter((name
) => name
!== 'default')
180 typeof entryModule
[name
] === `object` ||
181 typeof entryModule
[name
] === `function`
183 .map((name
) => [name
, entryModule
[name
]])
184 .reduce((reserved
, [name
, value
]) => {
186 const staticNames
= value
&&
187 typeof value
=== 'object' ? Object
.getOwnPropertyNames(value
).filter(isStaticOrProtoName
) :
188 typeof value
=== 'function' ? Object
.getOwnPropertyNames(value
).filter(isStaticOrProtoName
) : [];
190 const instanceNames
= (typeof value
=== `function` && Object
.getOwnPropertyNames(value
.prototype || {}) || []).filter(isStaticOrProtoName
);
192 return [...reserved
, { exportName
: name
, staticNames
, instanceNames
}];
196 function apacheHeader() {
197 return `// Licensed to the Apache Software Foundation (ASF) under one
198 // or more contributor license agreements. See the NOTICE file
199 // distributed with this work for additional information
200 // regarding copyright ownership. The ASF licenses this file
201 // to you under the Apache License, Version 2.0 (the
202 // "License"); you may not use this file except in compliance
203 // with the License. You may obtain a copy of the License at
205 // http://www.apache.org/licenses/LICENSE-2.0
207 // Unless required by applicable law or agreed to in writing,
208 // software distributed under the License is distributed on an
209 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
210 // KIND, either express or implied. See the License for the
211 // specific language governing permissions and limitations
212 // under the License.`;