@/utils#logger TypeScript Examples

The following examples show how to use @/utils#logger. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ExpressionManager.ts    From pixi-live2d-display with MIT License 6 votes vote down vote up
/**
     * Loads an Expression. Errors in this method will not be thrown,
     * but be emitted with an "expressionLoadError" event.
     * @param index - Index of the expression in definitions.
     * @return Promise that resolves with the Expression, or with undefined if it can't be loaded.
     * @emits {@link ExpressionManagerEvents.expressionLoaded}
     * @emits {@link ExpressionManagerEvents.expressionLoadError}
     */
    protected async loadExpression(index: number): Promise<Expression | undefined> {
        if (!this.definitions[index]) {
            logger.warn(this.tag, `Undefined expression at [${index}]`);
            return undefined;
        }

        if (this.expressions[index] === null) {
            logger.warn(this.tag, `Cannot set expression at [${index}] because it's already failed in loading.`);
            return undefined;
        }

        if (this.expressions[index]) {
            return this.expressions[index] as Expression;
        }

        const expression = await this._loadExpression(index);

        this.expressions[index] = expression;

        return expression;
    }
Example #2
Source File: MotionManager.ts    From pixi-live2d-display with MIT License 6 votes vote down vote up
/**
     * Loads a Motion in a motion group. Errors in this method will not be thrown,
     * but be emitted with a "motionLoadError" event.
     * @param group - The motion group.
     * @param index - Index in the motion group.
     * @return Promise that resolves with the Motion, or with undefined if it can't be loaded.
     * @emits {@link MotionManagerEvents.motionLoaded}
     * @emits {@link MotionManagerEvents.motionLoadError}
     */
    async loadMotion(group: string, index: number): Promise<Motion | undefined> {
        if (!this.definitions[group] ?. [index]) {
            logger.warn(this.tag, `Undefined motion at "${group}"[${index}]`);
            return undefined;
        }

        if (this.motionGroups[group]![index] === null) {
            logger.warn(this.tag, `Cannot start motion at "${group}"[${index}] because it's already failed in loading.`);
            return undefined;
        }

        if (this.motionGroups[group]![index]) {
            return this.motionGroups[group]![index]!;
        }

        const motion = await this._loadMotion(group, index);

        if (this.destroyed) {
            return;
        }

        this.motionGroups[group]![index] = motion ?? null;

        return motion;
    }
Example #3
Source File: MotionState.ts    From pixi-live2d-display with MIT License 6 votes vote down vote up
/**
     * Requests the playback for a motion.
     * @param motion - The Motion, can be undefined.
     * @param group - The motion group.
     * @param index - Index in the motion group.
     * @param priority - The priority to be applied.
     * @return True if the request has been approved, i.e. the motion is allowed to play.
     */
    start(motion: any, group: string, index: number, priority: MotionPriority): boolean {
        if (priority === MotionPriority.IDLE) {
            this.setReservedIdle(undefined, undefined);

            if (this.currentPriority !== MotionPriority.NONE) {
                logger.log(this.tag, 'Cannot start idle motion because another motion is playing.', this.dump(group, index));
                return false;
            }
        } else {
            if (group !== this.reservedGroup || index !== this.reservedIndex) {
                logger.log(this.tag, 'Cannot start motion because another motion has taken the place.', this.dump(group, index));
                return false;
            }

            this.setReserved(undefined, undefined, MotionPriority.NONE);
        }

        if (!motion) {
            return false;
        }

        this.setCurrent(group, index, priority);

        return true;
    }
Example #4
Source File: SoundManager.ts    From pixi-live2d-display with MIT License 6 votes vote down vote up
// TODO: return an ID?
    /**
     * Creates an audio element and adds it to the {@link audios}.
     * @param file - URL of the sound file.
     * @param onFinish - Callback invoked when the playback has finished.
     * @param onError - Callback invoked when error occurs.
     * @return Created audio element.
     */
    static add(file: string, onFinish?: () => void, onError?: (e: Error) => void): HTMLAudioElement {
        const audio = new Audio(file);

        audio.volume = this._volume;
        audio.preload = 'auto';

        audio.addEventListener('ended', () => {
            this.dispose(audio);
            onFinish?.();
        });

        audio.addEventListener('error', (e: ErrorEvent) => {
            this.dispose(audio);
            logger.warn(TAG, `Error occurred on "${file}"`, e.error);
            onError?.(e.error);
        });

        this.audios.push(audio);

        return audio;
    }
Example #5
Source File: setup.ts    From pixi-live2d-display with MIT License 6 votes vote down vote up
/**
 * Promises the Cubism 4 runtime has been started up.
 * @return Promise that resolves if the startup has succeeded, rejects if failed.
 */
export function cubism4Ready(): Promise<void> {
    if (CubismFramework.isStarted()) {
        return Promise.resolve();
    }

    startupPromise ??= new Promise<void>(((resolve, reject) => {
        function startUpWithRetry() {
            try {
                startUpCubism4();
                resolve();
            } catch (e) {
                startupRetries--;

                if (startupRetries < 0) {
                    const err = new Error('Failed to start up Cubism 4 framework.');

                    (err as any).cause = e;

                    reject(err);
                    return;
                }

                logger.log('Cubism4', 'Startup failed, retrying 10ms later...');

                setTimeout(startUpWithRetry, 10);
            }
        }

        startUpWithRetry();
    }));

    return startupPromise;
}
Example #6
Source File: MotionManager.ts    From pixi-live2d-display with MIT License 5 votes vote down vote up
/**
     * Starts a motion as given priority.
     * @param group - The motion group.
     * @param index - Index in the motion group.
     * @param priority - The priority to be applied.
     * @return Promise that resolves with true if the motion is successfully started, with false otherwise.
     */
    async startMotion(group: string, index: number, priority = MotionPriority.NORMAL): Promise<boolean> {
        if (!this.state.reserve(group, index, priority)) {
            return false;
        }

        const definition = this.definitions[group]?.[index];

        if (!definition) {
            return false;
        }

        if (this.currentAudio) {
            // TODO: reuse the audio?
            SoundManager.dispose(this.currentAudio);
        }

        let audio: HTMLAudioElement | undefined;

        if (config.sound) {
            const soundURL = this.getSoundFile(definition);

            if (soundURL) {
                try {
                    // start to load the audio
                    audio = SoundManager.add(
                        this.settings.resolveURL(soundURL),
                        () => this.currentAudio = undefined,
                        () => this.currentAudio = undefined,
                    );

                    this.currentAudio = audio;
                } catch (e) {
                    logger.warn(this.tag, 'Failed to create audio', soundURL, e);
                }
            }
        }

        const motion = await this.loadMotion(group, index);

        if (audio) {
            const readyToPlay = SoundManager.play(audio)
                .catch(e => logger.warn(this.tag, 'Failed to play audio', audio!.src, e));

            if (config.motionSync) {
                // wait until the audio is ready
                await readyToPlay;
            }
        }

        if (!this.state.start(motion, group, index, priority)) {
            if (audio) {
                SoundManager.dispose(audio);
                this.currentAudio = undefined;
            }

            return false;
        }

        logger.log(this.tag, 'Start motion:', this.getMotionName(definition));

        this.emit('motionStart', group, index, audio);

        if (this.state.shouldOverrideExpression()) {
            this.expressionManager && this.expressionManager.resetExpression();
        }

        this.playing = true;

        this._startMotion(motion!);

        return true;
    }
Example #7
Source File: MotionState.ts    From pixi-live2d-display with MIT License 5 votes vote down vote up
/**
     * Reserves the playback for a motion.
     * @param group - The motion group.
     * @param index - Index in the motion group.
     * @param priority - The priority to be applied.
     * @return True if the reserving has succeeded.
     */
    reserve(group: string, index: number, priority: MotionPriority): boolean {
        if (priority <= MotionPriority.NONE) {
            logger.log(this.tag, `Cannot start a motion with MotionPriority.NONE.`);
            return false;
        }

        if (group === this.currentGroup && index === this.currentIndex) {
            logger.log(this.tag, `Motion is already playing.`, this.dump(group, index));
            return false;
        }

        if ((group === this.reservedGroup && index === this.reservedIndex) || (group === this.reservedIdleGroup && index === this.reservedIdleIndex)) {
            logger.log(this.tag, `Motion is already reserved.`, this.dump(group, index));
            return false;
        }

        if (priority === MotionPriority.IDLE) {
            if (this.currentPriority !== MotionPriority.NONE) {
                logger.log(this.tag, `Cannot start idle motion because another motion is playing.`, this.dump(group, index));
                return false;
            }

            if (this.reservedIdleGroup !== undefined) {
                logger.log(this.tag, `Cannot start idle motion because another idle motion has reserved.`, this.dump(group, index));
                return false;
            }

            this.setReservedIdle(group, index);
        } else {
            if (priority < MotionPriority.FORCE) {
                if (priority <= this.currentPriority) {
                    logger.log(this.tag, 'Cannot start motion because another motion is playing as an equivalent or higher priority.', this.dump(group, index));
                    return false;
                }

                if (priority <= this.reservePriority) {
                    logger.log(this.tag, 'Cannot start motion because another motion has reserved as an equivalent or higher priority.', this.dump(group, index));
                    return false;
                }
            }

            this.setReserved(group, index, priority);
        }

        return true;
    }
Example #8
Source File: Live2DFactory.ts    From pixi-live2d-display with MIT License 5 votes vote down vote up
/**
     * Loads a Motion and registers the task to {@link motionTasksMap}. The task will be automatically
     * canceled when its owner - the MotionManager instance - has been destroyed.
     * @param motionManager - MotionManager that owns this Motion.
     * @param group - The motion group.
     * @param index - Index in the motion group.
     * @return Promise that resolves with the Motion, or with undefined if it can't be loaded.
     */
    static loadMotion<Motion, MotionSpec>(motionManager: MotionManager<Motion, MotionSpec>, group: string, index: number): Promise<Motion | undefined> {
        // errors in this method are always handled
        const handleError = (e: any) => motionManager.emit('motionLoadError', group, index, e);

        try {
            const definition = motionManager.definitions[group] ?. [index];

            if (!definition) {
                return Promise.resolve(undefined);
            }

            if (!motionManager.listeners('destroy').includes(Live2DFactory.releaseTasks)) {
                motionManager.once('destroy', Live2DFactory.releaseTasks);
            }

            let tasks = Live2DFactory.motionTasksMap.get(motionManager);

            if (!tasks) {
                tasks = {};
                Live2DFactory.motionTasksMap.set(motionManager, tasks);
            }

            let taskGroup = tasks[group];

            if (!taskGroup) {
                taskGroup = [];
                tasks[group] = taskGroup;
            }

            const path = motionManager.getMotionFile(definition);

            taskGroup[index] ??= Live2DLoader.load({
                    url: path,
                    settings: motionManager.settings,
                    type: motionManager.motionDataType,
                    target: motionManager,
                })
                .then(data => {
                    const taskGroup = Live2DFactory.motionTasksMap.get(motionManager)?.[group];

                    if (taskGroup) {
                        delete taskGroup[index];
                    }

                    const motion = motionManager.createMotion(data, group, definition);

                    motionManager.emit('motionLoaded', group, index, motion);

                    return motion;
                })
                .catch(e => {
                    logger.warn(motionManager.tag, `Failed to load motion: ${path}\n`, e);
                    handleError(e);
                });

            return taskGroup[index]!;
        } catch (e) {
            logger.warn(motionManager.tag, `Failed to load motion at "${group}"[${index}]\n`, e);
            handleError(e);
        }

        return Promise.resolve(undefined);
    }
Example #9
Source File: Live2DFactory.ts    From pixi-live2d-display with MIT License 5 votes vote down vote up
/**
     * Loads an Expression and registers the task to {@link expressionTasksMap}. The task will be automatically
     * canceled when its owner - the ExpressionManager instance - has been destroyed.
     * @param expressionManager - ExpressionManager that owns this Expression.
     * @param index - Index of the Expression.
     * @return Promise that resolves with the Expression, or with undefined if it can't be loaded.
     */
    static loadExpression<Expression, ExpressionSpec>(expressionManager: ExpressionManager<Expression, ExpressionSpec>, index: number): Promise<Expression | undefined> {
        // errors in this method are always handled
        const handleError = (e: any) => expressionManager.emit('expressionLoadError', index, e);

        try {
            const definition = expressionManager.definitions[index];

            if (!definition) {
                return Promise.resolve(undefined);
            }

            if (!expressionManager.listeners('destroy').includes(Live2DFactory.releaseTasks)) {
                expressionManager.once('destroy', Live2DFactory.releaseTasks);
            }

            let tasks = Live2DFactory.expressionTasksMap.get(expressionManager);

            if (!tasks) {
                tasks = [];
                Live2DFactory.expressionTasksMap.set(expressionManager, tasks);
            }

            const path = expressionManager.getExpressionFile(definition);

            tasks[index] ??= Live2DLoader.load({
                    url: path,
                    settings: expressionManager.settings,
                    type: 'json',
                    target: expressionManager,
                })
                .then(data => {
                    const tasks = Live2DFactory.expressionTasksMap.get(expressionManager);

                    if (tasks) {
                        delete tasks[index];
                    }

                    const expression = expressionManager.createExpression(data, definition);

                    expressionManager.emit('expressionLoaded', index, expression);

                    return expression;
                })
                .catch(e => {
                    logger.warn(expressionManager.tag, `Failed to load expression: ${path}\n`, e);
                    handleError(e);
                });

            return tasks[index]!;
        } catch (e) {
            logger.warn(expressionManager.tag, `Failed to load expression at [${index}]\n`, e);
            handleError(e);
        }

        return Promise.resolve(undefined);
    }
Example #10
Source File: XHRLoader.ts    From pixi-live2d-display with MIT License 5 votes vote down vote up
/**
     * Creates a managed XHR.
     * @param target - If provided, the XHR will be canceled when receiving an "destroy" event from the target.
     * @param url - The URL.
     * @param type - The XHR response type.
     * @param onload - Load listener.
     * @param onerror - Error handler.
     */
    static createXHR<T = any>(
        target: Live2DLoaderTarget | undefined,
        url: string,
        type: XMLHttpRequestResponseType,
        onload: (data: T) => void,
        onerror: (e: Error) => void,
    ): XMLHttpRequest {
        const xhr = new XMLHttpRequest();

        XHRLoader.allXhrSet.add(xhr);

        if (target) {
            let xhrSet = XHRLoader.xhrMap.get(target);

            if (!xhrSet) {
                xhrSet = new Set([xhr]);
                XHRLoader.xhrMap.set(target, xhrSet);
            } else {
                xhrSet.add(xhr);
            }

            if (!target.listeners('destroy').includes(XHRLoader.cancelXHRs)) {
                target.once('destroy', XHRLoader.cancelXHRs);
            }
        }

        xhr.open('GET', url);
        xhr.responseType = type;
        xhr.onload = () => {
            if ((xhr.status === 200 || xhr.status === 0) && xhr.response) {
                onload(xhr.response);
            } else {
                (xhr.onerror as any)();
            }
        };
        xhr.onerror = () => {
            logger.warn(TAG, `Failed to load resource as ${xhr.responseType} (Status ${xhr.status}): ${url}`);
            onerror(new NetworkError('Network error.', url, xhr.status));
        };
        xhr.onabort = () => onerror(new NetworkError('Aborted.', url, xhr.status, true));
        xhr.onloadend = () => {
            XHRLoader.allXhrSet.delete(xhr);

            if (target) {
                XHRLoader.xhrMap.get(target)?.delete(xhr);
            }
        };

        return xhr;
    }
Example #11
Source File: model-middlewares.ts    From pixi-live2d-display with MIT License 5 votes vote down vote up
setupOptionals: Middleware<Live2DFactoryContext> = async (context, next) => {
    // wait until all has finished
    await next();

    const internalModel = context.internalModel;

    if (internalModel) {
        const settings = context.settings!;
        const runtime = Live2DFactory.findRuntime(settings);

        if (runtime) {
            const tasks: Promise<void>[] = [];

            if (settings.pose) {
                tasks.push(
                    Live2DLoader.load({
                            settings,
                            url: settings.pose,
                            type: 'json',
                            target: internalModel,
                        })
                        .then((data: ArrayBuffer) => {
                            internalModel.pose = runtime.createPose(internalModel.coreModel, data);
                            context.live2dModel.emit('poseLoaded', internalModel.pose);
                        })
                        .catch((e: Error) => {
                            context.live2dModel.emit('poseLoadError', e);
                            logger.warn(TAG, 'Failed to load pose.', e);
                        }),
                );
            }

            if (settings.physics) {
                tasks.push(
                    Live2DLoader.load({
                            settings,
                            url: settings.physics,
                            type: 'json',
                            target: internalModel,
                        })
                        .then((data: ArrayBuffer) => {
                            internalModel.physics = runtime.createPhysics(internalModel.coreModel, data);
                            context.live2dModel.emit('physicsLoaded', internalModel.physics);
                        })
                        .catch((e: Error) => {
                            context.live2dModel.emit('physicsLoadError', e);
                            logger.warn(TAG, 'Failed to load physics.', e);
                        }),
                );
            }

            if (tasks.length) {
                await Promise.all(tasks);
            }
        }
    }
}
Example #12
Source File: core.ts    From graphene with MIT License 5 votes vote down vote up
coreHandler: Middleware = async (req, res) => {
  if (req.body === "" || !Object.keys(req.body).length) {
    res
      .writeHead(400, { "Content-Type": "application/json" })
      .end(JSON.stringify({ msg: "Body can't be empty!" }));
    return;
  }

  try {
    const options = (await optionSchema.validate(req.body, {
      abortEarly: false
    })) as OptionSchema;
    const { image, format, length } = await generateImage(options);

    res
      .writeHead(200, {
        "Content-Type": `image/${format === "svg" ? "svg+xml" : format}`,
        "Content-Length": length
      })
      .end(image);
  } catch (err) {
    if (err instanceof ValidationError && err.name === "ValidationError") {
      res
        .writeHead(400, { "Content-Type": "application/json" })
        .end(JSON.stringify({ msg: err.errors }));
    }
    return;
  }

  /* c8 ignore start */
  await logger.info("Incoming POST request", {
    body: req.body || "",
    headers: {
      accept: req.headers.accept || "",
      "content-type": req.headers["content-type"] || "",
      origin: req.headers.origin || "",
      referer: req.headers.referer || "",
      "user-agent": req.headers["user-agent"] || ""
    },
    port: req.socket.remotePort || "",
    ipv: req.socket.remoteFamily || ""
  });
  /* c8 ignore end */
}