The MDN documentation says that Intl.Segmenter is supported in Deno version 1.8 and above. But when trying to use it, I get an error.
error: TS2339 [ERROR]: Property 'Segmenter' does not exist on type 'typeof Intl'.
My code is simply this:
const SEGMENTER = new Intl.Segmenter('en', { granularity: 'grapheme' });
And here's my Deno version info:
deno 1.20.4 (release, x86_64-unknown-linux-gnu)
v8 10.0.139.6
typescript 4.6.2
Am I missing something about why this wouldn't work?
It's there, but it doesn't seem to be in the type definitions, so that's why you are receiving the compiler error. You can either use a #ts- comment directive or the --no-check CLI run argument to avoid the compiler diagnostic and continue execution of your program:
example.ts:
const denoVersion = Deno.version.deno;
// #ts-expect-error
const segmenter = new Intl.Segmenter("en", { granularity: "grapheme" });
console.log({ denoVersion, segmenter });
> deno run example.ts
{ denoVersion: "1.20.4", segmenter: Intl.Segmenter {} }
Related
I adopted scalarType (datetime) following the code from this question GraphQL Nexus asNexusMethod showing type error
import { DateTimeResolver } from "graphql-scalars";
const DateTime = asNexusMethod(DateTimeResolver, "datetime");
const schema = makeSchema({
types: [Query, DateTime]
});
It runs fine. The date is returned in ISO date formats successfully.
But the TypeScript compiler still complains in code where the type is used.
export const CourseTemplateType = objectType({
name: "CourseTemplate",
definition(t) {
t.id("id");
t.string("courseNo");
t.datetime("createdAt"); //Red line here
},
});
Normally the nexus project should run with the command below which solve the type checking issue.
ts-node --transpile-only ./src/app.ts
But I don't know how to do that in Next.js. Because the project is already run with npm run dev. Is there any way to do it?
My Main goal is to create an Electron App (Windows) that locally stores data in an SQLite Database. And because of type safety I choose to use the Prisma framework instead of other SQLite Frameworks.
I took this Electron Sample Project and now try to include Prisma. Depending on what I try different problems do arrise.
1. PrismaClient is unable to be run in the Browser
I executed npx prisma generate and then try to execute this function via a button:
import { PrismaClient } from '#prisma/client';
onSqlTestAction(): void {
const prisma = new PrismaClient();
const newTestObject = prisma.testTable.create(
{
data: {
value: "TestValue"
}
}
);
}
When executing this in Electron I get this:
core.js:6456 ERROR Error: PrismaClient is unable to be run in the browser.
In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues
at new PrismaClient (index-browser.js:93)
at HomeComponent.onSqlTestAction (home.component.ts:19)
at HomeComponent_Template_button_click_7_listener (template.html:7)
at executeListenerWithErrorHandling (core.js:15281)
at wrapListenerIn_markDirtyAndPreventDefault (core.js:15319)
at HTMLButtonElement.<anonymous> (platform-browser.js:568)
at ZoneDelegate.invokeTask (zone.js:406)
at Object.onInvokeTask (core.js:28666)
at ZoneDelegate.invokeTask (zone.js:405)
at Zone.runTask (zone.js:178)
It somehow seems logical that Prisma cannot run in a browser. But I actually build a native app - with Electron that embeds a Browser. It seems to be a loophole.
2. BREAKING CHANGE: webpack < 5 used to include polyfills
So i found this Question: How to use Prisma with Electron
Seemed to be exactly what I looked for. But the error message is different (Debian binaries were not found).
The solution provided is to generate the prisma artifacts into the src folder instead of node_modules - and this leads to 19 polyfills errors. One for example:
./src/database/generated/index.js:20:11-26 - Error: Module not found: Error: Can't resolve 'path' in '[PATH_TO_MY_PROJECT]\src\database\generated'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
- install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "path": false }
And this repeats with 18 other modules. Since the error message to begin with was different I also doubt that this is the way to go.
I finally figured this out. What I needed to understand was, that all Electron apps consist of 2 parts: The Frontend Webapp (running in embedded Chromium) and a Node backend server. Those 2 parts are called IPC Main and IPC Renderer and they can communicate with each other. And since Prisma can only run on the main process which is the backend I had to send my SQL actions to the Electron backend and execute them there.
My minimal example
In the frontend (I use Angular)
// This refers to the node_modules folder of the Electron Backend, the folder where the main.ts file is located.
// I just use this import so that I can use the prisma generated classes for type safety.
import { TestTable } from '../../../app/node_modules/.prisma/client';
// Button action
onSqlTestAction(): void {
this.electronService.ipcRenderer.invoke("prisma-channel", 'Test input').then((value) => {
const testObject: TestTable = JSON.parse(value);
console.log(testObject);
});
The sample project I used already had this service to provide the IPC Renderer:
#Injectable({
providedIn: 'root'
})
export class ElectronService {
ipcRenderer: typeof ipcRenderer;
webFrame: typeof webFrame;
remote: typeof remote;
childProcess: typeof childProcess;
fs: typeof fs;
get isElectron(): boolean {
return !!(window && window.process && window.process.type);
}
constructor() {
// Conditional imports
if (this.isElectron) {
this.ipcRenderer = window.require('electron').ipcRenderer;
this.webFrame = window.require('electron').webFrame;
this.childProcess = window.require('child_process');
this.fs = window.require('fs');
// If you want to use a NodeJS 3rd party deps in Renderer process (like #electron/remote),
// it must be declared in dependencies of both package.json (in root and app folders)
// If you want to use remote object in renderer process, please set enableRemoteModule to true in main.ts
this.remote = window.require('#electron/remote');
}
}
And then in the Electron backend I first added "#prisma/client": "^3.0.1" to the package.json (for the Electron backend not the frontend). Then I added to the main.ts this function to handle the requests from the renderer:
// main.ts
ipcMain.handle("prisma-channel", async (event, args) => {
const prisma = new PrismaClient();
await prisma.testTable.create(
{
data: {
value: args
}
}
);
const readValue = await prisma.testTable.findMany();
return JSON.stringify(readValue);
})
This way of simply adding the IPC Main handler in the main.ts file of course is a big code smell but usefull as minimal example. I think I will move on with the achitecture concept presented in this article.
I'm exploring Deno with cvs files, but i got a problem with the parse.
I'm thinking that the problem come with the old dependencies;
deno info --unstable --no-check .\mod.ts
The majority are from #0.75 and I'm in the #1.5.
And I want to collaborate to help to solve problems in the Deno repo and not just downgrade to some stable version.
I'm using:
deno 1.5.0
v8 8.7.220.3
typescript 4.0.
I'm having having issue with this code:
import { join } from "https://deno.land/std/path/mod.ts";
import { parse } from "https://deno.land/std/encoding/csv.ts";
import { BufReader } from "https://deno.land/std/io/bufio.ts";
async function loadData() {
const path = join(".", "data.csv");
const file = await Deno.open(path);
const bufReader = new BufReader(file);
const result = await parse(bufReader, {
skipFirstRow: true,
comment: "#",
});
Deno.close(file.rid)
console.log(result)
}
await loadData();
The error:
error: TS2345 [ERROR]: Argument of type 'BufReader' is not assignable to parameter of type 'string | BufReader'.
Type 'import("https://deno.land/std/io/bufio.ts").BufReader' is not assignable to
type 'import("https://deno.land/std#0.75.0/io/bufio.ts").BufReader'.
Types have separate declarations of a private property 'buf'.
const result = await parse(bufReader, {
~~~~~~~~~
at...
In Deno #1.0.0 works fine
deno upgrade --version 1.0.0
And in #1.5.1 works fine too
deno upgrade --version 1.5.1
1.5.0 had many problems due to a change in the nature of the compiler. I suggest downgrading to a lower version or ultra to 1.5.1 to receive the fixes implemented later on.
You should import
import { BufReader } from "https://deno.land/std#0.75.0/io/bufio.ts";
instead of
import { BufReader } from "https://deno.land/std/io/bufio.ts";
Better approach:
But actual best practice in case of deno is to use deps.ts file for all your dependencies.
Create file deps.ts in the root directory and export your dependencies there.
// deps.ts
// Standard library dependencies
export { BufReader } from "https://deno.land/std#0.75.0/io/bufio.ts";
// Third party dependencies
// ...
and in your other files you should import from deps.ts. For example, if you had mod.ts file in the root directory:
import { BufReader } from "./deps.ts";
// ...
Good thing about this approach is that whenever you want to change version of your imported libraries you will have to change in one place instead of many.
Am getting this error after following the steps mentioned in the nativescript-plugin-firebase readme file.
JS: firebase.init error: TypeError: Cannot read property 'database' of
undefined
https://github.com/EddyVerbruggen/nativescript-plugin-firebase
but i dont really understand nor do i know how to solve that.
the version of the plugin am using is : 6.4.0
with tns 4.1.2
EDIT: init code, from app.js
var firebase = require("nativescript-plugin-firebase");
firebase.init({ persist: true
// Optionally pass in properties for database, authentication and cloud messaging,
// see their respective docs.
}).then(
function (instance) {
console.log("firebase.init done");
},
function (error) {
console.log("firebase.init error: " + error);
}
);
I finally solved it by installing the plugin manually via the CLI (i initially installed it through NativeScript sidekick) apparently they didnt take in count the fact that some plugins may require some user inputs, to do write specific config file (which nativescript-plugin-firebase), so by installing it manually i got to provide the user input needed, it got configured and it worked!
I'm facing a strange problem on Meteor and I can't resolve it :
I'm developping a WebRTC app using Meteor, PeerJS and AdapterJS (which give an WebRTC plugin for unsupported browser like Safari or IE). These two libs are downloaded using NPM : meteor npm install peerjs/adapterjs
So in my view's controller I have :
view.js
//import Peer from 'peerjs'; => same error with "import"
//import AdapterJS from 'adapterjs';
Template.view.onRendered(function(){
AdapterJS = require("adapterjs");
Peer = require("peerjs");
//var peerkey="..."
var peer = new Peer({
key: peerkey, // get a free key at http://peerjs.com/peerserver
debug: 3,
config: {'iceServers': [
{ url: 'stun:stun.l.google.com:19302' },
{ url: 'stun:stun1.l.google.com:19302' },
]}
});
But when I run my controller, I get an exception because "console" is undefined inside peerjs/util.js function when calling the peerjs constructor :
Uncaught TypeError: Cannot read property 'log' of undefined
Strangly, when I only require "peerjs", there is no exeption...
I tried to change the order of require functions but it won't work.
Other variable like "alert", "window.console" work and are defined inside the module but "console" not.. :/
Any suggestion can help ^^
Thanks in advance.
EDIT : If I add a breakpoint on the first line of node_module/peerjs/lib/util.js, I see that the "console" variable is "undefined" inside util.js but .... it is defined inside the caller function (fileEvaluate) !
EDIT2 : I tried something else to check if the code inside adapterjs redefine or change something : I put 'require("adapterjs")' inside a timeout function with a long delay (10 seconds) and .... console is still undefined inside peer module ! But when I comment require("adapterjs"), no error, console is defined ! I think that Meteor do something special before running the controller script depending on require functions...
EDIT3 : Here is a git repo to test the project : gitlab.com
If you display the dev console, you will see exceptions.
I found a solution, although I don't fully understand it myself. It's something to do with the way that Meteor imports modules, and Peerjs runs afoul of that.
Basically I copied node_modules/peerjs/dist/peer.js into the client directory, so that Meteor will load it "as is".
A small change to main.js as follows:
import './main.html';
// I placed peer.js from the node_modules/peerjs/dist/peer.js into the client folder and it works fine
// import {Peer} from 'peerjs';
import {AdapterJS as Adapter} from 'adapterjs';
Template.hello.onCreated(function helloOnCreated() {
// counter starts at 0
window.peer = new Peer({
and it works fine :)
I see in line 860+ of adapter.js that console is being defined (part of the shim) from https://github.com/Temasys/AdapterJS/blob/master/source/adapter.js
// IE 9 is not offering an implementation of console.log until you open a console
if (typeof console !== 'object' || typeof console.log !== 'function') {
/* jshint -W020 */
console = {} || console;
// Implemented based on console specs from MDN
// You may override these functions
console.log = function (arg) {};
console.info = function (arg) {};
console.error = function (arg) {};
This code defines the console if it doesn't find one to it's liking? Does this mean you are using IE9 or some other incompatible browser?
Try pasting this into your console and see what it tells you:
if (typeof console !== 'object' || typeof console.log !== 'function') alert("Console not present, needs to be shimmed?"); else console.log("console is ok");
Presumably the reason you are using adapter.js is for compatibility purposes - this will help you trouble shoot it. Please let me know what you find, as I will be following you down this path :)