Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Shared Resources] dart-sass implementation #2134

Merged
merged 13 commits into from
Jan 18, 2024
6 changes: 6 additions & 0 deletions lib/src/js.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import 'js/exception.dart';
import 'js/exports.dart';
import 'js/compile.dart';
import 'js/compiler.dart';
import 'js/legacy.dart';
import 'js/legacy/types.dart';
import 'js/legacy/value.dart';
Expand All @@ -24,6 +25,11 @@ void main() {
exports.compileAsync = allowInteropNamed('sass.compileAsync', compileAsync);
exports.compileStringAsync =
allowInteropNamed('sass.compileStringAsync', compileStringAsync);
exports.initCompiler = allowInteropNamed('sass.initCompiler', initCompiler);
exports.initAsyncCompiler =
allowInteropNamed('sass.initAsyncCompiler', initAsyncCompiler);
exports.Compiler = compilerClass;
exports.AsyncCompiler = asyncCompilerClass;
exports.Value = valueClass;
exports.SassBoolean = booleanClass;
exports.SassArgumentList = argumentListClass;
Expand Down
104 changes: 104 additions & 0 deletions lib/src/js/compiler.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import 'dart:js_util';

import 'package:node_interop/js.dart';

import 'compile.dart';
import 'compile_options.dart';
import 'reflection.dart';
import 'utils.dart';

class Compiler {
jamesnw marked this conversation as resolved.
Show resolved Hide resolved
jamesnw marked this conversation as resolved.
Show resolved Hide resolved
bool _disposed = false;

void throwIfDisposed() {
if (_disposed) {
jsThrow(JsError('Compiler has already been disposed.'));
}
}
}

class AsyncCompiler extends Compiler {
final Set<Promise> _compilations = {};
jamesnw marked this conversation as resolved.
Show resolved Hide resolved
jamesnw marked this conversation as resolved.
Show resolved Hide resolved

/// Adds a compilation to the pending set and removes it when it's done.
void _addCompilation(Promise compilation) {
_compilations.add(compilation);
compilation.then((value) {
_compilations.remove(compilation);
}, (error) {
_compilations.remove(compilation);
});
}
}

/// The JS API Compiler class
///
/// See https://github.com/sass/sass/spec/tree/main/js-api/compile.d.ts for
jamesnw marked this conversation as resolved.
Show resolved Hide resolved
/// details.
final JSClass compilerClass = () {
var jsClass = createJSClass('sass.Compiler', () => Compiler());
jamesnw marked this conversation as resolved.
Show resolved Hide resolved

jsClass.defineMethods({
'compile': (Compiler self, String path, [CompileOptions? options]) {
self.throwIfDisposed();
return compile(path, options);
},
'compileString': (Compiler self, String source,
[CompileStringOptions? options]) {
self.throwIfDisposed();
return compileString(source, options);
},
'dispose': (Compiler self) {
self._disposed = true;
},
});

getJSClass(Compiler()).injectSuperclass(jsClass);
return jsClass;
}();

/// Returns an instance of the JS API Compiler class
///
/// See https://github.com/sass/sass/spec/tree/main/js-api/compile.d.ts for
/// details.
Compiler initCompiler() => Compiler();

/// The JS AsyncCompiler class
///
/// See https://github.com/sass/sass/spec/tree/main/js-api/compile.d.ts for
/// details.
final JSClass asyncCompilerClass = () {
var jsClass = createJSClass('sass.AsyncCompiler', () => AsyncCompiler());

jsClass.defineMethods({
'compileAsync': (AsyncCompiler self, String path,
[CompileOptions? options]) {
self.throwIfDisposed();
var compilation = compileAsync(path, options);
self._addCompilation(compilation);
return compilation;
},
'compileStringAsync': (AsyncCompiler self, String source,
[CompileStringOptions? options]) {
self.throwIfDisposed();
var compilation = compileStringAsync(source, options);
self._addCompilation(compilation);
return compilation;
},
'dispose': (AsyncCompiler self) {
self._disposed = true;
return futureToPromise((() async {
await Future.wait(self._compilations.map(promiseToFuture<Object>));
})());
}
});

getJSClass(AsyncCompiler()).injectSuperclass(jsClass);
return jsClass;
}();

/// Resolves an instance of the JS API AsyncCompiler class
///
/// See https://github.com/sass/sass/spec/tree/main/js-api/compile.d.ts for
/// details.
Promise initAsyncCompiler() => futureToPromise((() async => AsyncCompiler())());
4 changes: 4 additions & 0 deletions lib/src/js/exports.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ class Exports {
external set compileStringAsync(Function function);
external set compile(Function function);
external set compileAsync(Function function);
external set initCompiler(Function function);
external set initAsyncCompiler(Function function);
external set Compiler(JSClass function);
external set AsyncCompiler(JSClass function);
external set info(String info);
external set Exception(JSClass function);
external set Logger(LoggerNamespace namespace);
Expand Down
4 changes: 4 additions & 0 deletions tool/grind.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ void main(List<String> args) {
'compileAsync',
'compileString',
'compileStringAsync',
'initCompiler',
'initAsyncCompiler',
'Compiler',
'AsyncCompiler',
'Logger',
'SassArgumentList',
'SassBoolean',
Expand Down
Loading