Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
You can’t perform that action at this time.