Create a gist now

Instantly share code, notes, and snippets.

Line by line reader in cljs
(ns cljs-line-reader.core
(:refer-clojure :exclude [flush])
(:require clojure.string
[cljs.core.async :refer [>!]])
(:require-macros [cljs.core.async.macros :refer [go]]))
(def fs (js/require "fs"))
(def stream (js/require "stream"))
(def ^:const eol (.-EOL (js/require "os"))) ;;eg "\n" or "\r\n"
(defn- transform [chunk encoding done]
(this-as this
(let [data (if (.-_lastLineData this)
(str (.-_lastLineData this) chunk)
(str chunk))
lines (clojure.string/split data (js/RegExp. eol "g"))]
(set! (.-_lastLineData this) (last lines))
(doseq [line (butlast lines)]
(.push this line))
(done))))
(defn- flush [done]
(this-as this
(if (.-_lastLineData this)
(.push this (.-_lastLineData this)))
(set! (.-_lastLineData this) nil)
(done)))
(defn read-file-cb [file-name cb]
(let [line-reader (.Transform stream #js {:objectMode true})
source (.createReadStream fs file-name)]
(set! (.-_transform line-reader) transform)
(set! (.-_flush line-reader) flush)
(.pipe source line-reader)
(.on line-reader "readable"
(fn []
(when-let [line (.read line-reader)]
(cb (str line)) ;;callback with each line
(recur))))
nil))
(defn read-file-chan [file-name out-chan]
(let [line-reader (.Transform stream #js {:objectMode true})
source (.createReadStream fs file-name)]
(set! (.-_transform line-reader) transform)
(set! (.-_flush line-reader) flush)
(.pipe source line-reader)
(.on line-reader "readable"
(fn []
(go
(loop []
(when-let [line (.read line-reader)]
(>! out-chan (str line)) ;;push line to chan
(recur))))))
nil))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment