Skip to content

Commit

Permalink
@produck/duck:
Browse files Browse the repository at this point in the history
[ADDED] Utils::throwNotInstalled
@produck/duck-log:
[FIXED] not allow register() after installed
@produck/duck-runner:
[FIXED] use Duck::Utils::throwNotInstalled
[FIXED] use idiom
@produck/duck-web:
[FIXED] not allow build application before installed
  • Loading branch information
lichaozhy committed Nov 25, 2024
1 parent 21822ef commit 9719720
Show file tree
Hide file tree
Showing 12 changed files with 121 additions and 81 deletions.
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ typings/
.vscode

# Development debug
.debug.mjs
*.ign*
*.gen*

# Duck dist
packages/**/index.cjs
packages/**/version.mjs
packages/**/version.mjs
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"deps:install": "npm -v && npm i",
"lint": "eslint --fix packages/**/*.mjs",
"test": "npm run build:extract --workspaces && npm run test --workspaces",
"coverage": "c8 --exclude=**/*.spec.mjs --reporter=lcov npm run test",
"coverage": "c8 --exclude=**/*.spec.mjs --reporter=lcov npm test",
"publish": "npm run lint && npm test && lerna publish --no-private"
},
"devDependencies": {
Expand Down
16 changes: 10 additions & 6 deletions packages/duck-log/src/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,28 @@ const DuckLogComponent = (options = {}) => {
...meta,
install: ({ Kit }, next) => {
const map = new Map();
let installed = false;

const register = Object.freeze((category, options = {}) => {
if (installed) {
Ow.Error.Common('Can NOT register log category after installed.');
}

const register = (category, options = {}) => {
assertCategory(category);

if (map.has(category)) {
return Ow.Error.Common(`The category(${category}) is existed.`);
Ow.Error.Common(`The category(${category}) is existed.`);
}

map.set(category, new Logger.Handler({ label: category, ...options}));
};

Object.freeze(register);
});

Kit.Log = new Proxy(register, {
get: (_target, category) => {
assertCategory(category);

if (!map.has(category)) {
return Ow.Error.Common(`Category logger(${category}) is NOT defined.`);
Ow.Error.Common(`Category logger(${category}) is NOT defined.`);
}

return map.get(category).proxy;
Expand All @@ -52,6 +55,7 @@ const DuckLogComponent = (options = {}) => {
}

next();
installed = true;
},
});
};
Expand Down
60 changes: 42 additions & 18 deletions packages/duck-log/test/DuckLog.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -42,37 +42,61 @@ describe('DuckLog', function () {
});

describe('::register()', function () {
it('should register a new logger.', function () {
const Kit = Duck.define({
id: 'foo',
components: [DuckLog.Component()],
})();

Kit.Log('bar', { label: 'bar' });
Kit.Log('baz');
it('should register a new logger.', async function () {
await new Promise((resolve) => {
Duck.define({
id: 'foo',
components: [DuckLog.Component()],
}, function ({ Log }) {
Log('bar', { label: 'bar' });
Log('baz');
resolve();
})();
});
});

it('should throw if bad category.', function () {
const Kit = Duck.define({
id: 'foo',
components: [DuckLog.Component()],
})();
it('should throw if bad category.', async function () {
await new Promise(resolve => {
Duck.define({
id: 'foo',
components: [DuckLog.Component()],
}, function ({ Log }) {
assert.throws(() => Log(1), {
name: 'TypeError',
message: 'Invalid "category", one "string" expected.',
});

resolve();
})();
});

assert.throws(() => Kit.Log(1), {
name: 'TypeError',
message: 'Invalid "category", one "string" expected.',
});

it('should throw if duplicated category.', async function () {
await new Promise(resolve => {
Duck.define({
id: 'foo',
components: [DuckLog.Component({ foo: {} })],
}, function ({ Log }) {
assert.throws(() => Log('foo'), {
name: 'Error',
message: 'The category(foo) is existed.',
});

resolve();
})();
});
});

it('should throw if duplicated category.', function () {
it('should throw if installed.', function () {
const Kit = Duck.define({
id: 'foo',
components: [DuckLog.Component({ foo: {} })],
})();

assert.throws(() => Kit.Log('foo'), {
name: 'Error',
message: 'The category(foo) is existed.',
message: 'Can NOT register log category after installed.',
});
});
});
Expand Down
20 changes: 6 additions & 14 deletions packages/duck-runner/src/index.mjs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as Ow from '@produck/ow';
import EventEmitter from 'node:events';
import { defineComponent, defineAny } from '@produck/duck';
import { T } from '@produck/mold';
import { Assert } from '@produck/idiom';
import { defineComponent, defineAny, Utils } from '@produck/duck';

import * as Runner from './Runner/index.mjs';
import * as Options from './Options.mjs';
Expand All @@ -21,12 +20,10 @@ const DuckRunnerComponent = (...args) => {
...meta,
install: ({ Kit }, next) => {
const manager = new Runner.Manager();
const runner = Kit.Runner = {};
const runner = Kit.Runner = { start: Utils.throwNotInstalled };

Kit.Bus = new EventEmitter();

runner.start = () => Ow.Error.Common('Installation not completed.');

for (const name in modes) {
manager.Mode(name, modes[name]);
}
Expand All @@ -38,21 +35,16 @@ const DuckRunnerComponent = (...args) => {

const play = roles[name](RoleKit);

if (!T.Native.Function(play)) {
Ow.Invalid('play <= role()', 'function <= role()');
}
Assert.Type.Function(play, 'play <= role()', 'function <= role()');

manager.Role(name, play);
}

next();

runner.start = async function start(mode) {
if (!T.Native.String(mode)) {
Ow.Invalid('mode', 'string');
}

return await manager.run(mode, Kit);
Assert.Type.String(mode, 'mode');
await manager.run(mode, Kit);
};

Object.freeze(runner);
Expand Down
9 changes: 7 additions & 2 deletions packages/duck-web/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Schema } from '@produck/mold';

export interface ApplicationKit extends Duck.ProductKit {}

type Application = (...args: any[]) => RequestListener;
type Application = <T>(...args: T[]) => RequestListener;
type Provider = (Kit: ApplicationKit) => Application;

interface Descriptor {
Expand All @@ -13,9 +13,14 @@ interface Descriptor {
description?: string;
}

interface ApplicationBuilder {
<T>(id: string, ...args: T[]): RequestListener;
}

interface WebRegistry {
register: (descriptor: Descriptor) => void;
Application: (id: string, ...args: any[]) => RequestListener;
Application: ApplicationBuilder;
App: ApplicationBuilder;
}

type Options = Array<Descriptor>;
Expand Down
44 changes: 23 additions & 21 deletions packages/duck-web/src/index.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as Ow from '@produck/ow';
import { defineComponent, defineAny } from '@produck/duck';
import { T } from '@produck/mold';
import { Assert } from '@produck/idiom';
import { defineComponent, defineAny, Utils } from '@produck/duck';

import * as Preset from './Preset.mjs';
import * as Options from './Options.mjs';
Expand Down Expand Up @@ -32,48 +32,50 @@ const DuckWebComponent = (options = [DEFAULT_APPLICATION]) => {
const { id, provider, description } = finalDescriptor;

if (map.has(id)) {
return Ow.Error.Common(`Duplicate Application(${id}).`);
Ow.Error.Common(`Duplicate Application(${id}).`);
}

const ApplicationKit = Kit(`Application<${id}>`);
const Application = provider(ApplicationKit);

if (!T.Native.Function(Application)) {
return Ow.Invalid('.provider()=>', 'function');
}
Assert.Type.Function(Application, '.provider()=>');

const ApplicationProxy = (...args) => {
const requestListener = Application(...args);

if (!T.Native.Function(requestListener)) {
return Ow.Invalid(`Application(${id})=>`, '(req, res) => any');
}
Assert.Type.Function(requestListener, `Application(${id})=>`);

return requestListener;
};

map.set(id, { id, description, ApplicationProxy });
};

const Application = function Application(id, ...args) {
if (!T.Native.String(id)) {
return Ow.Invalid('id', 'string');
}
for (const Application of staticApplicationList) {
register(Application);
}

const Web = Kit.Web = {
register,
Application: Utils.throwNotInstalled,
get App() {
return this.Application;
},
};

next();

Web.Application = function Application(id, ...args) {
Assert.Type.String(id, 'id');

if (!map.has(id)) {
return Ow.Error.Common(`No application(${id}) existed.`);
Ow.Error.Common(`No application(${id}) existed.`);
}

return map.get(id).ApplicationProxy(...args);
};

Kit.Web = Object.freeze({ register, Application, App: Application });

next();

for (const Application of staticApplicationList) {
register(Application);
}
Object.freeze(Web);
},
});
};
Expand Down
5 changes: 3 additions & 2 deletions packages/duck-web/test/DuckWeb.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,11 @@ describe('DuckWeb', function () {
Kit.Web.Application('Foo');
}, {
name: 'TypeError',
message: 'Invalid "Application(Foo)=>", one "(req, res) => any" expected.',
message: 'Invalid "Application(Foo)=>", one "function" expected.',
});

});

it('should throw if not installed.');
});
});

Expand Down
2 changes: 1 addition & 1 deletion packages/duck-workspace/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ declare module '@produck/duck' {
}

export namespace Options {
const Schema: Schema<WorkspaceOptions>;
export const Schema: Schema<WorkspaceOptions>;

export function normalize(options: WorkspaceOptions): WorkspaceOptions;
}
Loading

0 comments on commit 9719720

Please sign in to comment.